顯示的執行計劃與實際不一致,並且速度奇慢
阿新 • • 發佈:2019-01-27
今天遇到一個問題,explain看到執行計劃是沒問題,但是執行起來速度奇慢,先看下問題吧。
說明下環境,centos 6.5 32G記憶體 表資料量 8億多
mysql> explain select * from sjkk_gcjl where jgsj>='2010-01-20 00:00:00' AND jgsj<='2015-05-20 00:00:00' and hpys = '2' and csys='A' ORDER BY jgsj DESC,jlbh DESc; +----+-------------+-----------+------+---------------------------------+---------+---------+-------------+---------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------+------+---------------------------------+---------+---------+-------------+---------+-------------+ | 1 | SIMPLE | sjkk_gcjl | ref | index08,index09,index10,index11 | index09 | 22 | const,const | 4875345 | Using where | +----+-------------+-----------+------+---------------------------------+---------+---------+-------------+---------+-------------+
select * from sjkk_gcjl where jgsj>='2010-01-20 00:00:00' AND jgsj<='2015-05-20 00:00:00' and hpys = '2' and csys='A' ORDER BY jgsj DESC,jlbh DESc;
......
100 rows in set (6min 36sec)
KEY `index09` (`csys`,`hpys`,`jgsj`,`jlbh`);從執行計劃看是沒有問題的,index09已經避免了排序,並且特別適合這個sql,理論不應該這麼慢的,懷疑資料庫真正執行時走的不是index09.
強制使用index09,發現在毫秒級返結果,這可以確定上面的猜想,資料庫實際沒有使用index09.
select * from sjkk_gcjl force index(index09) where jgsj>='2010-01-20 00:00:00' AND jgsj<='2015-05-20 00:00:00' and hpys = '2' and csys='A'
ORDER BY jgsj DESC,jlbh DESC;
.....
<pre name="code" class="html">100 rows in set (0.00 sec)
看看索引的統計資訊,發現Cardinality全是NULl。
mysql> show index from sjkk_gcjl; +-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | sjkk_gcjl | 1 | index09 | 1 | csys | A | NULL | NULL | NULL | | BTREE | | | | sjkk_gcjl | 1 | index09 | 2 | hpys | A | NULL | NULL | NULL | | BTREE | | | | sjkk_gcjl | 1 | index09 | 3 | jgsj | A | NULL | NULL | NULL | | BTREE | | | | sjkk_gcjl | 1 | index09 | 4 | jlbh | A | NULL | NULL | NULL | | BTREE | | | .....
收集下統計資訊。
analyze table sjkk_gcjl;
+-------------------------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+-------------------------+---------+----------+----------+
| changzhou_9yi.sjkk_gcjl | analyze | status | OK |
+-------------------------+---------+----------+----------+
1 row in set (1 hour 7 min 55.56 sec)
再次檢視索引的統計資訊。
mysql> show index from sjkk_gcjl;
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| sjkk_gcjl | 1 | index09 | 1 | csys | A | 56 | NULL | NULL | | BTREE | | |
| sjkk_gcjl | 1 | index09 | 2 | hpys | A | 224 | NULL | NULL | | BTREE | | |
| sjkk_gcjl | 1 | index09 | 3 | jgsj | A | 199409376 | NULL | NULL | | BTREE | | |
| sjkk_gcjl | 1 | index09 | 4 | jlbh | A | 797637506 | NULL | NULL | | BTREE | | |
......
再次執行,毫秒級返回結果。
select * from sjkk_gcjl where jgsj>='2010-01-20 00:00:00' AND jgsj<='2015-05-20 00:00:00' and hpys='2' and csys='A' ORDER BY jgsj DESC,jlbh DESC LIMIT 100;
....
100 rows in set (0.00 sec)