mysql 菜鸟优化

应用场景一:有一张很大的数据表,表的数据条数以亿计,每条数据有一个id进行标示,我们想要提取出一批指定id的数据(以百万计),怎么进行加速呢。

1.首先先将指定id的数据放入数据库中,

”load data local infile filename into tabletablename”

其中数据放在/tmp的文件夹下,将数据表建为内存表,

“create table tablename ()engine = myisam”或者是内存表无所谓

2.我们将sql语句写成

Select * from bigtable left join smalltableon btable.id=stable.id;

这样有用吗?实际上观测来说是没有什么用的,效率上没有任何提升。大部分时间消耗都在数据第一次被载入时,第一次载入的时间为20s,以后的每次查询3s结束,由此可以看出似乎影响不大。

3.我们将大表和小表的位置调换,结果发现效果一样,所以这个方法的优化手段究竟怎样才有效呢?

在上面的场景中,我们做了一个对比,结果是匪夷所思的

1.1         select count (1) from (select idfrom btable right join (select id from stable)s on stable.id =btable.id)b; 这句话运行了5分钟

1.2         select count (1) from (select idfrom btable )b right join (select id from stable)s on s.id =b.id;

运行了2分钟,

第二个场景,将数据库中一个大表的数据读出来,一次进行处理,这里的坑是什么呢?

大表的数据没办法一次读进内存,所以得分段读。一般就是用limit m,n来完成,但是这样并不能加快效率。因为假如limit 10000,10。前10000条数据都要丢弃,但是为了取这10条数据,就要遍历前面的10000条数据,所以这样是不行的。

最好的方法,给表格加一列id ,设为index,或者primary key,

分段选取的时候就写 id<max_index and id>min_index就可以了

因为id建了索引,所以找起来就很快了。



insert ignore 和 replace into

INSERT IGNORE 与INSERT INTO的区别就是INSERT IGNORE会忽略数据库中已经存在 的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据。这样就可以保留数据库中已经存在数据,达到在间隙中插入数据的目的。


replace into 跟 insert 功能类似,不同点在于:replace into 首先尝试插入数据到表中, 1. 如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据。 2. 否则,直接插入新数据。


要注意的是:插入数据的表必须有主键或者是唯一索引!否则的话,replace into 会直接插入数据,这将导致表中出现重复的数据。


MySQL replace into 有三种形式:
1. replace into tbl_name(col_name, ...) values(...)
2. replace into tbl_name(col_name, ...) select ...
3. replace into tbl_name set col_name=value, ...



插入多条数据:

conn = MySQLdb.connect(host = “localhost”, user = “root”, passwd = “password”, db = “myDB”, charset=’utf8′)
cursor = conn.cursor()
sql = “insert into myTable (created_day,name,count) values(%s,%s,%s) ON DUPLICATE KEY UPDATE count=count+values(count)”
args=[("2012-08-27","name1",100),("2012-08-27","name1",200),("2012-08-27","name2",300)]
try:
cursor.executemany(sql, args)
except Exception as e:
print0(“执行MySQL: %s 时出错:%s” % (sql, e))
finally:
cursor.close()
conn.commit()
conn.close()



索引:加入一个操作频繁读取where column=A

不如给那一列加入索引 对吗

alter table ****.**** add key  `mtype`(`mtype`);

select count(1),left(evil_number,3),if(locate('local',model)>0,1,0) as model_0 from  detect_evil_number_sum  where stat_date>='20180228' and phone1_city ='北京市' and cheated_type=15 group by if(locate('local',model)>0,1,0),left(evil_number,3);


猜你喜欢

转载自blog.csdn.net/cjneo/article/details/54882239