Mysql
使用索引時加快 COUNT(*)
我有一個類似的表(簡化):
CREATE TABLE books ( id INT AUTO_INCREMENT, category INT NOT NULL, PRIMARY KEY (id), KEY (category) );
這張桌子已經結束
10,000,000 rows
,在附近12 categories
。所以每個類別的平均值為833,333 books
.查詢計數時:
SELECT COUNT(*) FROM books WHERE category=1;
即使它在查詢時使用索引,這也需要很長時間才能完成(幾秒鐘)。您將如何優化它?
以前,我每次插入書籍時都會增加一個數字(插入到一個與類別 -> 書籍計數相關的表中。)但是我們的程式碼很複雜,很多地方插入或刪除書籍。我知道用 解決這個問題是可能的
EVENTS
,但我問也許我錯過了一個 MySQL 功能。
查詢會很慢,因為
category
索引的基數很低。有 12 個類別,因此查詢平均會讀取索引的 1/12 部分。您無法改進此查詢。您的原始方法可以提高整體性能。與其手動更新
book_count
,不如在 INSERT 和 DELETE 事件上創建觸發器。**更新:**證明查詢將部分讀取索引
category
mysql> select count(*) from books; +----------+ | count(*) | +----------+ | 1000 | +----------+ 1 row in set (0.00 sec) mysql> select category, count(*) from books group by 1; +----------+----------+ | category | count(*) | +----------+----------+ | 0 | 50 | | 1 | 77 | | 2 | 88 | | 3 | 84 | | 4 | 102 | | 5 | 79 | | 6 | 79 | | 7 | 73 | | 8 | 84 | | 9 | 76 | | 10 | 87 | | 11 | 83 | | 12 | 38 | +----------+----------+ 13 rows in set (0.01 sec) mysql> flush status; Query OK, 0 rows affected (0.00 sec) mysql> select count(*) from books where category = 6; +----------+ | count(*) | +----------+ | 79 | +----------+ 1 row in set (0.00 sec) mysql> show status like 'Hand%'; +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | Handler_commit | 1 | | Handler_delete | 0 | | Handler_discover | 0 | | Handler_external_lock | 2 | | Handler_mrr_init | 0 | | Handler_prepare | 0 | | Handler_read_first | 0 | | Handler_read_key | 1 | | Handler_read_last | 0 | | Handler_read_next | 79 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 0 | | Handler_rollback | 0 | | Handler_savepoint | 0 | | Handler_savepoint_rollback | 0 | | Handler_update | 0 | | Handler_write | 0 | +----------------------------+-------+ 18 rows in set (0.01 sec)