给定表格:
CREATE TABLE `sample` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`vendorid` VARCHAR(45) NOT NULL,
`year` INT(10) NOT NULL,
`title` TEXT NOT NULL,
`description` TEXT NOT NULL
PRIMARY KEY (`id`) USING BTREE
)
Run Code Online (Sandbox Code Playgroud)
表规模:700万以上。除 id 外,所有字段都不是唯一的。
简单查询:
SELECT * FROM sample WHERE title='milk'
Run Code Online (Sandbox Code Playgroud)
需要 45 到 60 秒才能完成。
尝试在标题和描述上放置唯一索引,但收到 1170 错误。
我该如何优化它?将非常感谢您的建议。
And*_*yer 12
如果您预计不会有很多行,或者您只想返回少量行,那么非唯一索引title就是最佳选择。由于此列是一种TEXT数据类型,因此您需要以某种方式限制长度,我选择了 100。
create index sample_idx01 on sample (title (100))
Run Code Online (Sandbox Code Playgroud)
默认情况下,索引不需要唯一性。
title字段上的索引可能会有所帮助,就像安德鲁提到的那样,因为是的,您通常希望对查询的谓词建立索引。但是,您的示例查询引起我注意的另一个问题是它正在使用SELECT *.
当您使用 时SELECT *,您使用的反模式可能会影响查询性能并导致使用次优查询计划。我的猜测(需要查看EXPLAIN ANALYZE)是您当前获得的查询计划是针对整个聚集索引(整个表)的扫描。即使在 上添加二级索引之后,情况可能仍然如此title。
相反,您应该只明确列出SELECT该给定查询实际需要的列,并可能将它们添加到辅助索引键中(title在定义中的列之后)。或者,如果此查询非常常用并且确实需要选择所有列,则您应该将title其作为聚集(主)索引的一部分,然后该索引将自动包含聚集在 上的表的所有字段title。
但无论如何,您应该停止使用SELECT *并始终明确列出您需要的列(即使它是表的所有列),以提高查询的可读性和可维护性。