2012-11-04 112 views
2

以下查詢在MySQL 5.0.67中以0.3秒爲單位執行,在MySQL 5.1.56中以3.0秒執行。爲什麼它在後面的版本中慢了十倍?爲什麼這個MySQL查詢在MySQL 5.1.56中這麼慢?

(數據庫從5.0.67導出並導入到56年5月1日,因此結構是相同的。)

SET @num :=0, @current_shop_id := NULL, @current_product_id := NULL; 

#this query limits the results of the query within it by row number (so that only 10 products get displayed per store) 

SELECT * FROM (

#this query adds row numbers to the query within it 

SELECT *, @num := IF(@current_shop_id = shop_id, IF(@current_product_id=product_id,@num,@num+1), 0) AS row_number, @current_shop_id := shop_id AS shop_dummy, @current_product_id := product_id AS product_dummy FROM (

SELECT shop, shops.shop_id AS 
shop_id, p1.product_id AS product_id 
    FROM products p1 
    INNER JOIN sex ON 
    sex.product_id=p1.product_id AND 
    sex.sex=0 AND 
    sex.date >= (SUBDATE(NOW(),INTERVAL 7 DAY)) INNER JOIN 
    shops ON 
    shops.shop_id = p1.shop_id 

    ORDER BY shop 
) AS testtable 

) AS rowed_results WHERE 
rowed_results.row_number>=0 AND 
rowed_results.row_number<(0+10) 

解釋計劃此查詢在5.0.67

id select_type table type possible_keys key key_len ref rows Extra 
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5433 Using where 
2 DERIVED <derived3> ALL NULL NULL NULL NULL 5433  
3 DERIVED sex ALL product_id_2,product_id NULL NULL NULL 379571 Using where; Using temporary; Using filesort 
3 DERIVED p1 ref PRIMARY,shop_id,shop_id_2,product_id,shop_id_3 product_id 4 mydatabase.sex.product_id 1  
3 DERIVED shops eq_ref PRIMARY PRIMARY 4 mydatabase.p1.shop_id 1  

EXPLAIN在56年5月1日

1 PRIMARY <derived2> ALL NULL NULL NULL NULL 491 Using where 
2 DERIVED <derived3> ALL NULL NULL NULL NULL 491 
3 DERIVED shops ALL PRIMARY NULL NULL NULL 163 Using filesort 
3 DERIVED p1 ref PRIMARY,shop_id,shop_id_2,product_id,shop_id_3 shop_id_2 4 mydatabase.shops.shop_id 41 
3 DERIVED sex eq_ref product_id_2,product_id product_id_2 5 mydatabase.p1.product_id 1 Using where 

指標

計劃爲此查詢0

產品表5.0.67

Keyname Type Cardinality Action Field 
PRIMARY PRIMARY  502437    product_id 
shop_id UNIQUE 502437    shop_id 
link 
title_2 UNIQUE 502437    title 
image 
brand INDEX 38649   brand 
title INDEX 251218    title 
date  INDEX 125609    date 
shop_id_2 INDEX 87    shop_id 
product_id INDEX 502437    product_id 
date 
shop_id_3 INDEX 125609    shop_id 
date 
sale_date INDEX 187    sale_date 

產品表,61年5月1日

Action Keyname Type Unique Packed Column Cardinality Collation Null Comment 
Edit Drop PRIMARY BTREE Yes No product_id 493078 A  
Edit Drop shop_id BTREE Yes No shop_id 0 A  
link 493078 A 
Edit Drop title_2 BTREE Yes No title 0 A  
image 493078 A 
Edit Drop brand BTREE No No brand 123269 A YES 
Edit Drop title BTREE No No title 493078 A  
Edit Drop date BTREE No No date 41089 A  
Edit Drop shop_id_2 BTREE No No shop_id 12026 A  
Edit Drop product_id BTREE No No product_id 493078 A  
date 493078 A 
Edit Drop shop_id_3 BTREE No No shop_id 12026 A  
date 49307 A 
Edit Drop sale_date BTREE No No sale_date 5940 A 

商店表5.0.67

Keyname Type Cardinality Action Field 
PRIMARY PRIMARY  163    shop_id 

商店表5.161

Action Keyname Type Unique Packed Column Cardinality Collation Null Comment 
Edit Drop PRIMARY BTREE Yes No shop_id 163 A 

性表爲MySQL 61年5月1日

[mysqladmin] 
user=username 

[mysqld] 
basedir=/opt/bitnami/mysql 
datadir=/opt/bitnami/mysql/data 
port=3306 
socket=/opt/bitnami/mysql/tmp/mysql.sock 
tmpdir=/opt/bitnami/mysql/tmp 

character-set-server=UTF8 
collation-server=utf8_general_ci 

max_allowed_packet=16M 
wait_timeout = 120 
long_query_time = 1 
log_slow_queries 
log_queries_not_using_indexes 
query_cache_limit=2M 
query_cache_type=1 
query_cache_size=8M 
innodb_additional_mem_pool_size=8M 
innodb_buffer_pool_size=16M 
#innodb_log_file_size=128M 
#tmp_table_size=64M 
#max_connections = 2500 
#max_user_connections = 2500 
#innodb_flush_method=O_DIRECT 
#key_buffer_size=64M 

[mysqld_safe] 
mysqld=mysqld.bin 

[client] 
default-character-set=UTF8 
port=3306 
socket=/opt/bitnami/mysql/tmp/mysql.sock 

[manager] 
port=3306 
socket=/opt/bitnami/mysql/tmp/mysql.sock 
pid-file=/opt/bitnami/mysql/tmp/manager.pid 
default-mysqld-path=/opt/bitnami/mysql/bin/mysqld.bin 

5.0.67

Keyname Type Cardinality Action Field 
product_id_2  UNIQUE 506094    product_id 
sex 
product_id INDEX 506094    product_id 

性表,61年5月1日

Action Keyname Type Unique Packed Column Cardinality Collation Null Comment 
Edit Drop product_id_2 BTREE Yes No product_id 0 A  
sex 496732 A 
Edit Drop product_id BTREE No No product_id 496732 A 

my.cnf文件我發現,如果我把外查詢添加行號,時間差下降到0.3秒和0.7秒。

SELECT shop, shops.shop_id AS 
shop_id, p1.product_id AS product_id 
    FROM products p1 
    INNER JOIN sex ON 
    sex.product_id=p1.product_id AND 
    sex.sex=0 AND 
    sex.date >= (SUBDATE(NOW(),INTERVAL 7 DAY)) INNER JOIN 
    shops ON 
    shops.shop_id = p1.shop_id 

    ORDER BY shop 
+1

難道指標導出/導入正確/可言? –

+0

在兩個數據庫上運行'EXPLAIN SELECT ...'並比較 –

+0

您是否使用了相同的'mysql.ini'文件? – Jocelyn

回答

1

新數據庫中的某些索引顯示基數0,而在舊數據庫中它們顯示較大的值。這可能意味着新的數據庫有一個錯誤的想法是多麼有效率的指數。分析表格會更新表中保存的值的相關信息,以便數據庫知道要選擇哪個索引。

你有每個表運行

ANALYZE TABLE table_name 

。或者,你可以分析所有表用一個命令:

ANALYZE TABLE products, shops, ... 

編號:http://dev.mysql.com/doc/refman/5.1/en/analyze-table.html

0

嘗試把一些USE INDEX(http://dev.mysql.com/doc/refman/5.1/en/index-hints.html),和經驗,試圖找到正確的順序使用索引。在大型查詢中,mysql通常很難找到正確的索引來使用。