Mysql

針對 SUM 和 Order By 優化 MySQL InnoDB 查詢

  • April 19, 2019

我有一個 1.3M 行和 670MB 大小的 MySQL InnoDB 表:

+----------------+--------------+------+-----+---------+-------+
|     Field      |     Type     | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+-------+
| item_name      | varchar(255) | NO   |     | NULL    |       |
| item_link      | varchar(50)  | NO   | PRI | NULL    |       |
| item_price     | varchar(10)  | NO   |     | NULL    |       |
| shop_name      | varchar(40)  | NO   | MUL | NULL    |       |
| sales          | int(11)      | NO   |     | NULL    |       |
| sale_date      | varchar(10)  | NO   | PRI | NULL    |       |
+----------------+--------------+------+-----+---------+-------+

CREATE TABLE `sales` 
 ( 
    `item_name`      VARCHAR(255) NOT NULL, 
    `item_link`      VARCHAR(50) NOT NULL, 
    `item_price`     VARCHAR(10) NOT NULL, 
    `shop_name`      VARCHAR(40) NOT NULL, 
    `sales`          INT(11) NOT NULL, 
    `sale_date` VARCHAR(10) NOT NULL, 
    PRIMARY KEY (`item_link`, `sale_date`), 
    KEY `sale_date` (`sale_date`), 
    KEY `shop_name` (`shop_name`) 
 ) 
engine=innodb 
DEFAULT charset=latin1 

這是我的 3GB RAM 伺服器的 my.ini 設置:

key_buffer = 16M
max_allowed_packet = 16M
sort_buffer_size = 8M
net_buffer_length = 8K
read_buffer_size = 2M
read_rnd_buffer_size = 16M
myisam_sort_buffer_size = 8M
log_error = "mysql_error.log"
innodb_autoinc_lock_mode=0
join_buffer_size = 8M
thread_cache_size = 8
thread_concurrency = 8
query_cache_size = 64M
query_cache_limit = 2M
ft_min_word_len = 4
thread_stack = 192K
tmp_table_size = 64M

innodb_buffer_pool_size = 1.5G
innodb_additional_mem_pool_size = 16M
innodb_log_file_size = 350M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 120
innodb_write_io_threads = 8
innodb_read_io_threads = 8
innodb_thread_concurrency = 16
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90

當我執行下一個查詢時,返回結果需要 10-15 秒:

SELECT item_name, 
      item_link, 
      item_price, 
      shop_name, 
      sales 
FROM   `sales` 
WHERE  sale_date = '2019-04-18' 

甚至更長的時間:

SELECT item_name, 
      item_link, 
      item_price, 
      shop_name, 
      Sum(sales) AS sales 
FROM   `sales` 
WHERE  sale_date BETWEEN '2019-04-17' AND '2019-04-18' 
GROUP  BY item_link 

item_link我有一個and的複合主鍵sale_date,我還為shop_nameand添加了索引sale_date

我不知道還能做什麼,我認為對於這樣一個相對較小的表來說,這種查詢應該執行得更快,請幫忙!

您在 item_link 和 sale_date 上有索引,但您沒有使用 item_link。當 where 子句中沒有使用索引的第一列時,執行查詢時往往會跳過索引。

根據你的 where 子句計劃你的索引,在這種情況下 sale_date 會很好

謝謝,

引用自:https://dba.stackexchange.com/questions/235254