2011-12-20 4 views
3

У меня есть следующий запрос:Почему этот запрос исследует так много строк, когда EXPLAIN выглядит так хорошо?

SELECT mdg.id AS mdg_id, vdk.id AS vdisk_id, vdk.name AS vdisk_name, vdk.objKey AS vdisk_key, 
     vdc.type AS copy_type, vde.copy_id AS copy_id, mdk.id AS mdisk_id, vde.number_extents AS extent_count, 
     IFNULL(ter.name,'generic_hdd') AS mdisk_tier, mdg.snapKey, vde.objKey AS row_key 
    FROM  mdisk_grp AS mdg 
    INNER JOIN vdiskcopy AS vdc ON mdg.snapKey = vdc.snapKey AND mdg.id = vdc.mdisk_grp_id 
    INNER JOIN vdisk  AS vdk ON vdc.owner = vdk.objKey 
    INNER JOIN vdiskextent AS vde ON vdk.snapKey=vde.snapKey AND vdk.id = vde.vdisk_id AND vdc.copy_id = vde.copy_id 
    INNER JOIN mdisk  AS mdk ON vde.id = mdk.id AND vde.snapKey = mdk.snapKey 
    LEFT JOIN tier_mdisk AS tmk ON tmk.mdisk_objKey = mdk.objKey 
    LEFT JOIN tier  AS ter ON tmk.tier_objKey = ter.objKey 
    WHERE mdg.snapKey= '333'; 

Я вижу его часто в журнале медленных запросов (ведьмы различных значений mdg.snapKey, конечно); например:

# [email protected]: svcControl[svcControl] @ localhost [] 
# Query_time: 2577 Lock_time: 0 Rows_sent: 11469 Rows_examined: 354942843 

Тот факт, что он работает долго, неудивительно, учитывая количество исследуемых строк.

Однако, когда я EXPLAIN запрос, я вижу

+----+-------------+-------+--------+---------------------------------------------------------+--------------------+---------+------------------------+------+---------------------+ 
| id | select_type | table | type | possible_keys           | key    | key_len | ref     | rows | Extra    | 
+----+-------------+-------+--------+---------------------------------------------------------+--------------------+---------+------------------------+------+---------------------+ 
| 1 | SIMPLE  | tmk | system | mdisk_objKey_idx          | NULL    | NULL | NULL     | 0 | const row not found | 
| 1 | SIMPLE  | ter | const | PRIMARY             | NULL    | NULL | NULL     | 1 |      | 
| 1 | SIMPLE  | mdg | ref | mdisk_grp_id_idx,snapIdx        | snapIdx   | 2  | const     | 11 |      | 
| 1 | SIMPLE  | vdc | ref | snapIdx,mdgIdIdx,ownerIdx        | mdgIdIdx   | 5  | svcObjects.mdg.id  | 1 | Using where   | 
| 1 | SIMPLE  | vdk | eq_ref | PRIMARY,vdisk_id_idx,snapIdx       | PRIMARY   | 3  | svcObjects.vdc.owner | 1 |      | 
| 1 | SIMPLE  | mdk | ref | mdisk_id_idx,snapKey_idx        | snapKey_idx  | 2  | svcObjects.vdk.snapKey | 16 |      | 
| 1 | SIMPLE  | vde | ref | vdiskextent_id_idx,vdiskextent_vdisk_id_idx,snapKey_idx | vdiskextent_id_idx | 5  | svcObjects.mdk.id  | 23 | Using where   | 
+----+-------------+-------+--------+---------------------------------------------------------+--------------------+---------+------------------------+------+---------------------+ 

Умножив все эти строки вместе доходит до чуть более 4000 (без учета 0 в колонке)

Это появляется что план выполнения игнорируется.

Есть ли способ запустить запрос, а затем получить отчет и какой план выполнения фактически соблюден? Или я не понимаю этого вывода?

UPDATE я заметил, что Cardinality для некоторых из моих индексов был NULL, так что я ANALYZE d всех таблиц. Последние EXPLAIN отчеты:

+----+-------------+-------+--------+---------------------------------------------------------+--------------------------+---------+----------------------+------+---------------------+ 
| id | select_type | table | type | possible_keys           | key      | key_len | ref     | rows | Extra    | 
+----+-------------+-------+--------+---------------------------------------------------------+--------------------------+---------+----------------------+------+---------------------+ 
| 1 | SIMPLE  | tmk | system | mdisk_objKey_idx          | NULL      | NULL | NULL     | 0 | const row not found | 
| 1 | SIMPLE  | ter | const | PRIMARY             | NULL      | NULL | NULL     | 1 |      | 
| 1 | SIMPLE  | mdg | ref | mdisk_grp_id_idx,snapIdx        | snapIdx     | 2  | const    | 8 |      | 
| 1 | SIMPLE  | vdc | ref | snapIdx,mdgIdIdx,ownerIdx        | snapIdx     | 2  | const    | 1580 | Using where   | 
| 1 | SIMPLE  | vdk | eq_ref | PRIMARY,vdisk_id_idx,snapIdx       | PRIMARY     | 3  | svcObjects.vdc.owner | 1 |      | 
| 1 | SIMPLE  | vde | ref | vdiskextent_id_idx,vdiskextent_vdisk_id_idx,snapKey_idx | vdiskextent_vdisk_id_idx | 5  | svcObjects.vdk.id | 300 | Using where   | 
| 1 | SIMPLE  | mdk | ref | mdisk_id_idx,snapKey_idx        | mdisk_id_idx    | 5  | svcObjects.vde.id | 14 | Using where   | 
+----+-------------+-------+--------+---------------------------------------------------------+--------------------------+---------+----------------------+------+---------------------+ 

Это умножает до 53,088,000, что гораздо лучше, чем 354,942,843, которые были рассмотрены в медленном запросе.

Я догадываюсь, что мой вопрос теперь в том, что ... поведение, которое я видел, объясняется тем, что я сделал ... если показатели мощности равны NULL, тогда план выполнения окажется чрезмерно оптимистичным и может также привести к в 6-7 раз количество проверяемых строк?

+0

Каковы схемы таблицы? Особый интерес представляют определения индексов. – outis

ответ

Смежные вопросы