1. 程式人生 > >顯示的執行計劃與實際不一致,並且速度奇慢

顯示的執行計劃與實際不一致,並且速度奇慢

今天遇到一個問題,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)