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

假设如下:

我有两个问题:

  1. 我可以假设这是一个有效的查询还是应该向 nidx 列添加索引?
  2. 第一个问题的答案是否取决于特定的 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