以%开头的Like查询。可以考虑用全文索引。或利用Innodb的聚簇索引,扫索引比扫表快得多。例如:一个表有主键id,辅助索引name。现在想根据name模糊搜索 name like %end%,直接select * from table where name like %end%,会引起表的全扫描,效率低下。因为Innodb每个辅助索引中存的都是主键的值,所以可以改为select * from (select id from table
where name like %end%) a, table b where a.id = b.id; 这样子查询中因为id和name在辅助索引中满足了覆盖索引,只扫索引就可以拿到所有满足条件的id,然后根据id再去查询最终结果。
show profiles可以查看当前线程每个查询。show profile for query + id(show profiles得到的),可以看每一步的耗时。还可以进一步在cpu io block等级别查看在使用什么资源时,耗时高。例如:show profile cpu for query + id。
select * from information_schema.optimizer_trace; 查看跟踪文件。
sql语句优化:
insert:如果单个客户端插入多条,尽量insert into test values(1,2),(3,4),(5,6)如此同时插入,减少交互
order by:btree索引是有序存储的,可以利用。所以尽量减少额外的filesort,通过索引直接返回有序数据。做法:order by与where使用相同的索引、复合索引。并且order by的字段都是升序或都是降序。 如果做不到,排序操作很多,数据较多时,适当开大sort_buffer_size让排序尽量在内存中完成,这个值是每个线程独占的,多个线程就多个buffer,注意!
group by:默认情况下group by c1, c2会对c1,c2...的所有字段排序,如果不需要刻意通过显示的加一个order by null禁止排序,提高效率。
嵌套查询:有些情况可以使用连接代替。
or:保证每个列都能用到索引,会发现mysql处理时,将每个字段分别查询后进行了UNION操作。
分页查询:limit1000,10 会排序出前1010行,最后只去10行。效率低。
利用覆盖索引:子查询先利用覆盖索引查询到满足条件的主键,再利用主键回表查找记录。eg:select name, value from data order by name limit 1000, 10; 改为 select name, value from data a inner join (select id from data order by name limit 1000, 10) b on a.id = b.id;
纪录上一次结果的最后一个排序列的值,然后:where name > lastvalue order by name limit 10; 这种方法不适合排序字段有重复值的情况,会丢纪录。
SQL提示:
USE INDEX : 让mysql参考提供的索引。eg:select * from data use index (idx_id);
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn