SQL 查询性能 - 单条记录,按非索引列过滤,按索引列排序,记录在排序记录的顺序中接近
SQL query performance - single record, filtered by non-indexed column, sorted by indexed column, record is close in the sequence of sorted records
我有以下 (My)SQL 查询:
SELECT * FROM table WHERE nidx = x ORDER BY id DESC LIMIT 1
假设如下:
id
是索引字段
nidx
是一个非索引字段(假设它有一个数字类型)
x
是常数
- 具有
nidx = x
的记录在记录的有序序列中相对接近(假设它保证在顺序的前 1000 条记录中)
我有两个问题:
- 我可以假设这是一个有效的查询还是应该向
nidx
列添加索引?
- 第一个问题的答案是否取决于特定的 RDBMS(因此 MySQL、PostgreSQL、MSSQL、SQLite 可能会有所不同, ETC。)?如果是,MySQL 的情况如何?
过滤后应用排序。 ORDER BY
子句在这种情况下对搜索没有帮助。同样,除非您对 table 有一些明确的约束,表明这些值将接近,否则优化器不知道这一点,也无济于事。
如果您不能/不会在 nidx
上应用索引,可能有帮助的是首先获取 id = x
周围的记录,然后搜索这些记录。
类似...
SELECT
*
FROM
table
WHERE
id BETWEEN x - 1000 AND x + 1000
AND nidx = x
ORDER BY
id
LIMIT
1
-希望-这将允许优化器构建一个计划,其中首先找到 id=x
周围的 2000 条记录,然后仅手动搜索 nidx= x
.
的那 2000 条记录
您必须尝试看看,然后使用 EXPLAIN
准确了解按什么顺序执行的操作。
不过,总的来说,这是一个hack,不要太依赖它。最好修复索引。
- 这是适用于所有平台的建议
加索引就行了 :)
考虑到记录的数量,索引是更可取的。
MySQL 中的示例:
ALTER TABLE table ADD INDEX nidx_index (nidx)
您还可以为唯一值创建唯一索引:
ALTER TABLE table ADD UNIQUE INDEX nidx_index (nidx)
您可以为 nidx 字段使用索引,但您必须记住,这会使 UPDATE、INSERT 和 DELETE 查询效率更低。
使用 ORDER BY 和 GROUP BY 的 sql 查询中惩罚最严重的,因为它们是在最后执行的操作。如果没有必要,我会删除 ORDER BY
最后您可以使用 EXPLAIN 命令诊断 SQL 个查询
EXPLAIN SELECT * FROM table WHERE nidx = x ORDER BY id DESC
这里有一个使用 Explain 改进查询的小教程
https://dev.mysql.com/doc/workbench/en/wb-tutorial-visual-explain-dbt3.html
我有以下 (My)SQL 查询:
SELECT * FROM table WHERE nidx = x ORDER BY id DESC LIMIT 1
假设如下:
id
是索引字段nidx
是一个非索引字段(假设它有一个数字类型)x
是常数- 具有
nidx = x
的记录在记录的有序序列中相对接近(假设它保证在顺序的前 1000 条记录中)
我有两个问题:
- 我可以假设这是一个有效的查询还是应该向
nidx
列添加索引? - 第一个问题的答案是否取决于特定的 RDBMS(因此 MySQL、PostgreSQL、MSSQL、SQLite 可能会有所不同, ETC。)?如果是,MySQL 的情况如何?
过滤后应用排序。 ORDER BY
子句在这种情况下对搜索没有帮助。同样,除非您对 table 有一些明确的约束,表明这些值将接近,否则优化器不知道这一点,也无济于事。
如果您不能/不会在 nidx
上应用索引,可能有帮助的是首先获取 id = x
周围的记录,然后搜索这些记录。
类似...
SELECT
*
FROM
table
WHERE
id BETWEEN x - 1000 AND x + 1000
AND nidx = x
ORDER BY
id
LIMIT
1
-希望-这将允许优化器构建一个计划,其中首先找到 id=x
周围的 2000 条记录,然后仅手动搜索 nidx= x
.
您必须尝试看看,然后使用 EXPLAIN
准确了解按什么顺序执行的操作。
不过,总的来说,这是一个hack,不要太依赖它。最好修复索引。
- 这是适用于所有平台的建议
加索引就行了 :)
考虑到记录的数量,索引是更可取的。 MySQL 中的示例:
ALTER TABLE table ADD INDEX nidx_index (nidx)
您还可以为唯一值创建唯一索引:
ALTER TABLE table ADD UNIQUE INDEX nidx_index (nidx)
您可以为 nidx 字段使用索引,但您必须记住,这会使 UPDATE、INSERT 和 DELETE 查询效率更低。
使用 ORDER BY 和 GROUP BY 的 sql 查询中惩罚最严重的,因为它们是在最后执行的操作。如果没有必要,我会删除 ORDER BY
最后您可以使用 EXPLAIN 命令诊断 SQL 个查询
EXPLAIN SELECT * FROM table WHERE nidx = x ORDER BY id DESC
这里有一个使用 Explain 改进查询的小教程 https://dev.mysql.com/doc/workbench/en/wb-tutorial-visual-explain-dbt3.html