其他查询优化策略:
1.EXISTS 和 IN:
具体看表的大小,要符合小表驱动大表的原则
如
SELECT * FROM A WHERE id IN (SELECT id FROM B);——————①
SELECT * FROM A WHERE EXISTS (SELECT id FROM B WHERE B.id = A.id);——————②
若A为小表,则使用②EXISTS
若B为小表,则使用①IN
2.COUNT(*) he COUNT(具体字段):
问:在 MySQL 中统计数据表的行数,可以使用三种方式: SELECT COUNT(*) 、 SELECT COUNT(1) 和
SELECT COUNT(具体字段) ,使用这三者之间的查询效率是怎样的?
答:
1.COUNT(*)和COUNT(1)都是对所有结果进行COUNT,本质上没有区别,
①如果使用MyISAM存储引擎,则复杂度为O(1),因为MyISAM存储引擎中有一个mata信息记录了表中的记录数(row_count)而一致性则由表级锁来保证
②如果使用InnoDB存储引擎则复杂度为O(n),因为InnoDB支持事务,采用行级锁和MVCC机制,无法像MyISAM一样维护一个row_count变量,需要全表扫描
2.在InnoDB存储引擎中,如果采用COUNT(具体字段)来统计数据行数,要尽量使用二级索引,因为主键索引使用的是聚簇索引,包含的信息较多,而对于COUNT(*)和COUNT(1)来说,它们不需要查找具体的行,只是统计行数,系统会自动采用占用空间更小的二级索引来进行统计
如果存在多个二级索引,则会使用key_len更小的二级索引进行扫描,当没有二级索引的时候,才会使用主键索引来进行统计
3.关于SELECT * FROM 某个表:
在表查询中,建议明确字段,不要使用*作为查询的字段列表,推荐使用SELECT 具体字段 来进行查询
原因:
①:MySQL在解析的过程中,会通过查询数据字典将 ‘*‘ 转换为所有字段的名称,会大大的耗费资源和时间
②:无法使用覆盖索引
4.LIMIT 1 对优化的影响
针对的是会扫描全表的SQL语句,如果你可以确定结果集只有一条,那么加上LIMIT 1 的时候,当找到一条结果的时候就不会继续进行扫描了,这样会加快查询速度
如果数据表对字段已经建立了唯一索引,那么可以通过索引进行查询,不会对全表进行扫描,那么就不需要再加LIMIT 1
5.多使用COMMIT进行手动提交
COMMIT会释放资源:
1.回滚段上用户恢复数据的信息
2.被程序语句获得的锁
3.redo / undo log buffer中的空间
4.管理上述三种资源中的内部花费