首先我会写一些关于我的测试表的信息。这是 books 表,有 665647 行数据。下面您可以看到它的外观。
我对价格相同的书籍进行了 10 次相同的查询
select * from books where price = 10
Run Code Online (Sandbox Code Playgroud)
所有 10 个查询的执行时间为 9 秒 663 毫秒。
我尝试再次运行相同的 10 个查询。它们的执行时间为 21 秒 996 毫秒。
show index from books;
Run Code Online (Sandbox Code Playgroud)
为我显示了非常有线的数据。可能的值只有一个!
我做错了什么?我确信索引可以使我们的查询更快,而不是更慢。
我发现这个主题:MySQL索引减慢查询速度
,但说实话,我不太理解这一点,尤其是我的表格书中的基数列,此时价格字段有两个可能的值10和30仍然show index from books;显示1

@Edit1 SHOW CREATE TABLE 书籍
结果:
CREATE TABLE `books` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` text COLLATE utf8mb4_unicode_ci NOT NULL,
`isbn` bigint unsigned NOT NULL,
`price` double(8,2) unsigned NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`author_id` bigint unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `books_isbn_unique` (`isbn`),
KEY `books_author_id_foreign` (`author_id`),
KEY `books_price_index` (`price`),
CONSTRAINT `books_author_id_foreign` FOREIGN KEY (`author_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=665648 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
Run Code Online (Sandbox Code Playgroud)
@Edit2我添加了新索引create index nameIndex on books (name)
其中有很大的基数值。
当我尝试select * from books where name ='Inventore cumque quis.'
在索引创建之前和之后执行此查询时,我可以看到执行时间的差异。但我仍然不明白索引是如何工作的。我确信一件事 - 如果我在数据库中创建新索引,就会使用适合该索引的数据创建新的数据结构。例如,如果我有价格为 10、30 的 orws,我有两个“表”,其中包含这些价格的行。
有这么多相同的行是否现实price?从查询中返回 444K 行是否现实?我问这些是因为查询优化基于“正常”数据。
INDEX(price)当查找price出现次数较少的时,索引(例如)非常有用。事实上,如果优化器发现正在搜索的值出现超过大约 20% 的时间,它就会避开索引。相反,它会简单地忽略索引并执行您首先测试的操作 - 简单地扫描整个表,忽略任何不匹配的行。
你应该能够通过这样做看到
EXPLAIN select * from books where price = 10
Run Code Online (Sandbox Code Playgroud)
有和没有索引。或者,您可以尝试:
EXPLAIN select * from books IGNORE INDEX(books_price_index) where price = 10
EXPLAIN select * from books FORCE INDEX(books_price_index) where price = 10
Run Code Online (Sandbox Code Playgroud)
但是,...看来优化器并没有忽略索引。我看到 的“基数”price是“1”,这意味着该列中只有一个不同的值。这个“统计数据”要么不正确,要么具有误导性。请运行它并查看发生了什么变化:
ANALYZE TABLE books;
Run Code Online (Sandbox Code Playgroud)
这将通过一些随机探测重新计算统计数据,并可能将“1”更改为“2”。
一般建议:谨防针对伪造数据运行的基准。
| 归档时间: |
|
| 查看次数: |
902 次 |
| 最近记录: |