我正在嘗試盡可能快地執行 SQL 查詢。
只有一個表有約 1000 萬條記錄,該表有 3 個索引以便更快地讀取,但不幸的是我要從中選擇的列沒有。
讓我解釋一下:我想從表中選擇標題bugs(id, token, title, category, device, reported_at, created_at, updated_at):
我在做什么 :SELECT title FROM (SELECT id FROM bugs WHERE reported_at = '2020-08-30' and token = 'token660')
它可以作業,但速度很慢,雖然我使用了 2 個索引報告_at 和令牌,我怎樣才能加快速度?
這是索引:
{
"records": [
{
"Table": "bugs",
"Non_unique": 0,
"Key_name": "PRIMARY",
"Seq_in_index": 1,
"Column_name": "id",
"Collation": "A",
"Cardinality": 9791826,
"Sub_part": null,
"Packed": null,
"Null": "",
"Index_type": "BTREE",
"Comment": "",
"Index_comment": ""
},
{
"Table": "bugs",
"Non_unique": 1,
"Key_name": "index_bugs_on_category_and_token_and_reported_at",
"Seq_in_index": 1,
"Column_name": "category",
"Collation": "A",
"Cardinality": 1,
"Sub_part": null,
"Packed": null,
"Null": "YES",
"Index_type": "BTREE",
"Comment": "",
"Index_comment": ""
},
{
"Table": "bugs",
"Non_unique": 1,
"Key_name": "index_bugs_on_category_and_token_and_reported_at",
"Seq_in_index": 2,
"Column_name": "token",
"Collation": "A",
"Cardinality": 29946,
"Sub_part": null,
"Packed": null,
"Null": "YES",
"Index_type": "BTREE",
"Comment": "",
"Index_comment": ""
},
{
"Table": "bugs",
"Non_unique": 1,
"Key_name": "index_bugs_on_category_and_token_and_reported_at",
"Seq_in_index": 3,
"Column_name": "reported_at",
"Collation": "A",
"Cardinality": 6085027,
"Sub_part": null,
"Packed": null,
"Null": "YES",
"Index_type": "BTREE",
"Comment": "",
"Index_comment": ""
}
]
}
uj5u.com熱心網友回復:
您需要使用搜索條件的列創建索引。在這種情況下:
CREATE INDEX search_index
ON bugs (reported_at, token);
由于您使用等號搜索,因此應該很快。查詢必須是:
SELECT title FROM bugs WHERE reported_at = '2020-08-30' and token = 'token660'
如果無法更改資料庫,可以單獨選擇行,將它們相交,然后獲取標題:
SELECT r.title
FROM (
SELECT * FROM bugs WHERE reported_at = '2020-08-30'
) r
JOIN (
SELECT id FROM bugs WHERE token = 'token660'
) t
ON r.id = t.id
uj5u.com熱心網友回復:
在 MySQL中,多列索引只能使用最左邊的列。其他資料庫沒有這個限制。
這是因為 MySQL 索引(默認情況下)是B-Trees。多列索引是一棵樹。要使用索引(category, token, reported_at)MySQL 必須首先在類別樹中找到一個類別,然后在該類別中會有一個 token's 的子樹,最后在該類別和 token 中會有一個reported_at's 的子樹。
在您的情況下,您有一個多列索引(category, token, reported_at)。如果您只按類別搜索,MySQL 可以使用索引。或者按類別和標記,MySQL 可以使用索引。或按類別、令牌和報告的_at。
您正在按令牌和報告_at 搜索,但由于您不是按類別搜索,因此 MySQL 不會使用索引。它必須掃描類別索引中的每個條目以查找匹配的標記。其他資料庫在使用索引的方式上更加靈活,并且可能會嘗試這樣做,但 MySQL 不會。
Use The Index,Luke對MySQL中的多列索引有很好的解釋
通常,具有兩列以上的索引的價值值得懷疑。
因此,就像以前一樣,答案是在您正在搜索的欄位上創建一個新索引。或者使用更好的資料庫。
uj5u.com熱心網友回復:
SELECT id
FROM bugs
WHERE reported_at = '2020-08-30'
and token = 'token660'
需要這個復合索引:INDEX(token, reported_at)
我不知道其余的胡言亂語是關于什么category的title。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/485556.html
