我有一个联合索引是这么建立的: typeid,verify,id,hits现在遇到一个问题,如果我在 where 条件中对 typeid 使用 in 的话,效率很慢,要全表扫描比如 select * from table where verify = 1 and typeid in (1,2,3) order by id desc limit 10非常慢,尤其是分页的时候
select * from table where verify = 1 and typeid in (1,2,3) order by id desc limit 100000,10
的时候,简直是场灾难,这个问题应该怎么解决呢?这条sql应该怎么写最好
select * from table where verify = 1 and typeid in (1,2,3) order by id desc limit 100000,10
的时候,简直是场灾难,这个问题应该怎么解决呢?这条sql应该怎么写最好
还有你的 show index from table
+----+-------------+-------------+-------+---------------+--------+---------+------+-------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+--------+---------+------+-------+-----------------------------+
| 1 | SIMPLE | tiyuxiu_art | range | typeid | typeid | 5 | NULL | 81072 | Using where; Using filesort |
+----+-------------+-------------+-------+---------------+--------+---------+------+-------+-----------------------------+
1 row in set (16.64 sec)
以下是索引:
mysql> show index from tiyuxiu_art
-> ;
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| tiyuxiu_art | 0 | PRIMARY | 1 | id | A | 153122 | NULL | NULL | | BTREE | |
| tiyuxiu_art | 0 | url | 1 | url | A | NULL | NULL | NULL | YES | BTREE | |
| tiyuxiu_art | 0 | initial | 1 | initial | A | NULL | NULL | NULL | YES | BTREE | |
| tiyuxiu_art | 1 | img | 1 | img | A | 153122 | NULL | NULL | YES | BTREE | |
| tiyuxiu_art | 1 | hot | 1 | hot | A | 2 | NULL | NULL | | BTREE | |
| tiyuxiu_art | 1 | typeid | 1 | typeid | A | 10 | NULL | NULL | | BTREE | |
| tiyuxiu_art | 1 | typeid | 2 | verify | A | 10 | NULL | NULL | | BTREE | |
| tiyuxiu_art | 1 | typeid | 3 | id | A | 153122 | NULL | NULL | | BTREE | |
| tiyuxiu_art | 1 | typeid | 4 | hits | A | 153122 | NULL | NULL | | BTREE | |
| tiyuxiu_art | 1 | hits | 1 | hits | A | 195 | NULL | NULL | | BTREE | |
+-------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
用到索引了,但是还是要Using filesort
我在网上看资料说 in 很费资源,像我这个能用什么语句来替代?
试一下不用索引时的速度。
MYSQL不应该这样处理吗:先通过 typeid 和 verify 进行筛选,然后 id 也在索引里,直接按索引里的id进行排序不就行了?还有并不是每条sql都有半数以上的记录符合条件,有少的,但是碰到多的的时候,会卡住,硬盘太烂了还有一点,就是如果我不用 in ,而是用 typeid=的时候,就直接用索引
比如mysql> explain select * from tiyuxiu_art where verify=1 and typeid = 2 order by id DESC limit 10 ;
+----+-------------+-------------+------+---------------+--------+---------+-------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+--------+---------+-------------+------+-------------+
| 1 | SIMPLE | tiyuxiu_art | ref | typeid | typeid | 5 | const,const | 8178 | Using where |
+----+-------------+-------------+------+---------------+--------+---------+-------------+------+-------------+
1 row in set (0.00 sec)
| tiyuxiu_art | 1 | typeid | 1 | typeid | A | 10 | NULL | NULL | | BTREE | |
| tiyuxiu_art | 1 | typeid | 2 | verify | A | 10 | NULL | NULL | | BTREE | |
| tiyuxiu_art | 1 | typeid | 3 | id | A | 153122 | NULL | NULL | | BTREE | |
| tiyuxiu_art | 1 | typeid | 4 | hits | A | 153122 | NULL | NULL | | BTREE | |
按 verify=1 and typeid = 2找到记录后,它的排序正好就是ID。
但如果你提 verify=1 and ( typeid = 2 or typeid = 3) 则你必须把2和3的都取出后,进行统一排序才能得出结果。
1 别用大结果集,别用in。或在in的那条sql语句前面加上,增大 排序缓冲区 的语句。sort_buffer_size,read_rnd_buffer_size ---试着调整这两个变量,看看效果如何
2 想别的办法,如 加大内存临时表,或把sql结果缓存起来。