Mysql

我可以使用外鍵索引作為獲取 INNODB 表中行數的快捷方式嗎?

  • July 30, 2013

我有一個包含大量行的表。

預設情況下,主鍵(一個自動遞增的整數)是索引的。

在等待返回行數時,我EXPLAIN在另一個視窗中做了一個,結果如下:

mysql> SELECT COUNT(1) FROM `gauge_data`;
+----------+
| COUNT(1) |
+----------+
| 25453476 |
+----------+
1 row in set (2 min 36.20 sec)


mysql> EXPLAIN SELECT COUNT(1) FROM `gauge_data`;
+----+-------------+------------+-------+---------------+-----------------+---------+------+----------+-------------+
| id | select_type | table      | type  | possible_keys | key             | key_len | ref  | rows     | Extra       |
+----+-------------+------------+-------+---------------+-----------------+---------+------+----------+-------------+
|  1 | SIMPLE      | gauge_data | index | NULL          | gauge_data_FI_1 | 5       | NULL | 24596487 | Using index |
+----+-------------+------------+-------+---------------+-----------------+---------+------+----------+-------------+
1 row in set (0.13 sec)

由於主鍵保證是唯一的,我可以只從 中EXPLAIN獲取行數並將其用作表的行數嗎?

順便說一句,我相信數字上的差異是由於越來越多的數據不斷添加到這個表中。

您不能相信 EXPLAIN 計劃的行數。為什麼?

每次在涉及 InnoDB 表的地方進行查詢優化時,InnoDB 儲存引擎都會對鍵的 BTREE 條目進行近似處理。它們的近似值因查詢而異。

只需執行SHOW INDEXES FROM guage_data;多次,每次都會得到一組不同的行數。您可以將 innodb_stats_on_metadata 設置為 0:

SET GLOBAL innodb_stats_on_metadata = 0;

這將導致SHOW INDEXES FROM guage_data;一遍又一遍地給出相同的數字。這仍然是弄巧成拙,因為無論如何行數仍然是近似的。您必須禁用元數據統計並執行分析表。再次,這是自欺欺人。

啟用 innodb_stats_on_metadata 時,總是會進行近似。我在 2011 年 6 月 21 日寫過這篇文章:MySQL 查詢優化器從哪裡讀取索引統計資訊?

鑑於這一切,SELECT id FROM guage_data如果 id 是 PRIMARY KEY,你最好這樣做。但是,請注意在您的 EXPLAIN 計劃中 MySQL 選擇遍歷gauge_data_FI_1索引。如果這張表是 InnoDB,這在世界上都是有意義的。為什麼?無論如何,每個非唯一索引都儲存 PRIMARY KEY 的 rowid。

這種行為對我來說似乎很奇怪。我沒有任何具有這種大小的表的 MySQL 數據庫,但是COUNT(*)在我的 Informix 和 MS SQL Server 數據庫中,具有比這更大的表的表可以立即執行。

你需要它有多精確?如果不准確但合理的估計很好,你可以使用這個:

SELECT TABLE_ROWS 
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'gauge_data'

資源

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