2013-10-30 48 views
1

我有一個SQL查詢需要大約1.81秒的時間來執行。我在phpMyAdmin中進行了描述,我發現99%的時間都花在「統計」上。查詢統計信息佔查詢時間的99%

有趣的是,如果我再添加一個連接,時間將增加到23秒,如果我刪除1個連接,時間將縮短到大約0.26秒。

我試過把product_id =放在attribute_id =的那裏加入。它並沒有改善績效,「統計」仍然使用99%的時間。

我試過group by p.id雖然性能略有提高,但'統計'仍然使用98%的時間。

有沒有一種方法來提高'統計'的性能或只是禁用它?

注意:我確實在所有PK/FK上都有索引。

有用信息

sqlfiddle here

大約150行的查詢返回。

ss_product table has 1k rows 
ss_product_attributes has 30 rows 
ss_product_attribute_varchars has 5000 rows 
ss_product_attribute_decimals has 10000 rows 

架構

ss_products has many ss_product_attribute_varchars 
ss_products has many ss_product_attribute_decimals 
ss_product_attribute_varchars belongs to ss_product_attributes 
ss_product_attribute_decimals belongs to ss_product_attributes 

------------- 
-ss_products- 
------------- 
- PK - id - 
------------- 

-------------------------------- 
-ss_product_attribute_varchars- 
-------------------------------- 
- PK - id      - 
- FK - product_id    - 
- FK - attribute_id   - 
-------------------------------- 

-------------------------------- 
-ss_products_attribute_decimals- 
-------------------------------- 
- PK - id      - 
- FK - product_id    - 
- FK - attribute_id   - 
-------------------------------- 

------------------------ 
-ss_products_attributes- 
------------------------ 
- PK - id    - 
------------------------ 

剖析

Starting     101 µs 
Checking Permissions  6 µs 
Checking Permissions  2 µs 
Checking Permissions  2 µs 
Checking Permissions  2 µs 
Checking Permissions  1 µs 
Checking Permissions  2 µs 
Checking Permissions  2 µs 
Checking Permissions  2 µs 
Checking Permissions  2 µs 
Checking Permissions  3 µs 
Opening Tables   47 µs 
System Lock    10 µs 
Init      35 µs 
Optimizing    21 µs 
Statistics    1.8 s  //1.8seconds!!!! 
Preparing    46 µs 
Executing    3 µs 
Sending Data    41 ms 
End      7 µs 
Query End    4 µs 
Closing Tables   12 µs 
Freeing Items   463 µs 
Logging Slow Query  3 µs 
Cleaning Up    9 µs 

查詢

select 
    aa.value as attribute_a, 
    bb.value as attribute_b, 
    cc.value as attribute_c, 
    dd.value as attribute_d, 
    ee.value as attribute_e, 
    ff.value as attribute_f, 
    gg.value as attribute_g, 
    hh.value as attribute_h, 
    ii.value as attribute_i 
from ss_products as p 
    inner join ss_product_attribute_varchars as aa 
    on p.id = aa.product_id 
    inner join ss_product_attribute_varchars as bb 
    on p.id = bb.product_id 
    inner join ss_product_attribute_varchars as cc 
    on p.id = cc.product_id 
    inner join ss_product_attribute_decimals as dd 
    on p.id = dd.product_id 
    inner join ss_product_attribute_decimals as ee 
    on p.id = ee.product_id 
    inner join ss_product_attribute_decimals as ff 
    on p.id = ff.product_id 
    inner join ss_product_attribute_varchars as gg 
    on p.id = gg.product_id 
    INNER JOIN ss_product_attribute_varchars AS hh 
    ON p.id = hh.product_id 
    INNER JOIN ss_product_attribute_varchars AS ii 
    ON p.id = ii.product_id 
where 
    aa.attribute_id = 8 AND 
    bb.attribute_id = 6 AND 
    cc.attribute_id = 7 AND 
    dd.attribute_id = 9 and 
    ee.attribute_id = 10 and 
    ff.attribute_id = 11 AND 
    gg.attribute_id = 20 AND 
    hh.attribute_id = 2 AND 
    ii.attribute_id = 3 

的解釋

id| select_type| table | type | possible_keys           |key           |key_len| ref     | rows| Extra 
1 | SIMPLE  | gg  | ref | fk_product_attribute_varchars_products1_idx,fk_pro... | attribute_id        | 4  | const    | 143 | 
1 | SIMPLE  | aa  | ref | fk_product_attribute_varchars_products1_idx,fk_pro... | fk_product_attribute_varchars_products1_idx | 4  | my_id.gg.product_id | 2 | Using where 
1 | SIMPLE  | cc  | ref | fk_product_attribute_varchars_products1_idx,fk_pro... | fk_product_attribute_varchars_products1_idx | 4  | my_id.gg.product_id | 2 | Using where 
1 | SIMPLE  | bb  | ref | fk_product_attribute_varchars_products1_idx,fk_pro... | fk_product_attribute_varchars_products1_idx | 4  | my_id.gg.product_id | 2 | Using where 
1 | SIMPLE  | ii  | ref | fk_product_attribute_varchars_products1_idx,fk_pro... | fk_product_attribute_varchars_products1_idx | 4  | my_id.aa.product_id | 2 | Using where 
1 | SIMPLE  | p  | eq_ref | PRIMARY            | PRIMARY          | 4  | my_id.aa.product_id | 1 | Using where; Using index 
1 | SIMPLE  | dd  | ref | fk_product_attribute_decimals_products1_idx,fk_pro... | fk_product_attribute_decimals_products1_idx | 4  | my_id.cc.product_id | 2 | Using where 
1 | SIMPLE  | ee  | ref | fk_product_attribute_decimals_products1_idx,fk_pro... | fk_product_attribute_decimals_products1_idx | 4  | my_id.ii.product_id | 2 | Using where 
1 | SIMPLE  | ff  | ref | fk_product_attribute_decimals_products1_idx,fk_pro... | fk_product_attribute_decimals_products1_idx | 4  | my_id.p.id   | 2 | Using where 
1 | SIMPLE  | hh  | ref | fk_product_attribute_varchars_products1_idx,fk_pro... | fk_product_attribute_varchars_products1_idx | 4  | my_id.cc.product_id | 2 | Using where 

完整的個人資料(如要求由雷蒙德Nijland)

+----------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+---------------+-------------------+-------------------+-------------------+-------+-----------------+---------------+-------------+ 
| Status    | Duration | CPU_user | CPU_system | Context_voluntary | Context_involuntary | Block_ops_in | Block_ops_out | Messages_sent | Messages_received | Page_faults_major | Page_faults_minor | Swaps | Source_function | Source_file | Source_line | 
+----------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+---------------+-------------------+-------------------+-------------------+-------+-----------------+---------------+-------------+ 
| starting    | 0.000151 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | NULL   | NULL   |  NULL | 
| checking permissions | 0.000005 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  4751 | 
| checking permissions | 0.000002 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  4751 | 
| checking permissions | 0.000003 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  4751 | 
| checking permissions | 0.000002 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  4751 | 
| checking permissions | 0.000003 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  4751 | 
| checking permissions | 0.000002 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  4751 | 
| checking permissions | 0.000005 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  4751 | 
| checking permissions | 0.000002 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  4751 | 
| checking permissions | 0.000002 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  4751 | 
| checking permissions | 0.000005 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  4751 | 
| Opening tables  | 0.000051 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_base.cc |  4838 | 
| System lock   | 0.000016 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | lock.cc  |   299 | 
| init     | 0.000046 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_select.cc |  2560 | 
| optimizing   | 0.000031 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_select.cc |   869 | 
| statistics   | 1.419911 | 1.404009 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_select.cc |  1060 | 
| preparing   | 0.000050 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_select.cc |  1082 | 
| executing   | 0.000003 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_select.cc |  1829 | 
| Sending data   | 0.018508 | 0.015600 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_select.cc |  2371 | 
| end     | 0.000007 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_select.cc |  2596 | 
| query end   | 0.000004 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  4440 | 
| closing tables  | 0.000018 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  4492 | 
| freeing items  | 0.000110 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  5640 | 
| logging slow query | 0.000004 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  1461 | 
| cleaning up   | 0.000008 | 0.000000 | 0.000000 |    NULL |    NULL |   NULL |   NULL |   NULL |   NULL |    NULL |    NULL | NULL | <unknown>  | sql_parse.cc |  1417 | 
+----------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+---------------+------------------+-------------------+-------------------+-------+-----------------+---------------+-------------+ 
+0

是什麼EXPLAIN說什麼? – Barmar

+0

@Barmar用EXPLAIN – Gab

+0

更新了這個問題@Gab旁註omg下一次使用的別名表示不是aa bb cc的別名,或者你可能想嘗試命名你的別名,敲打你的頭在鍵盤上。 –

回答

2

回答了這個問題出關,因爲一個評論doenst支持代碼格式。

統計輪廓輸出這一部分在C++源代碼中定義過的MySQL

/* Calculate how to do the join */ 
thd_proc_info(thd, "statistics"); 
if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) || 
thd->is_fatal_error) 
{ 
DBUG_PRINT("error",("Error: make_join_statistics() failed")); 
DBUG_RETURN(1); 
} 

但你仍然需要運行

SHOW PROFILE ALL FOR QUERY n 

所以我們可以看到,如果查詢是CPU或磁盤I/O有界。

我建議使用UNION ALL或使用分而治之的策略來分隔querys

+0

我添加了完整的配置文件我的問題 – Gab

+0

和MySQL服務器版本? –

+0

MySql版本5.5.27,InnoDB版本1.1.8 – Gab