SQL查询性能-单个记录,按非索引列过滤,按索引列排序,记录在排序记录序列中接近

问题描述

我有以下(我的)SQL查询

SELECT * FROM table WHERE nidx = x ORDER BY id DESC LIMIT 1

使用以下假设:

  • id一个索引字段
  • nidx一个非索引字段(假设它具有数字类型)
  • x一个常量
  • 带有nidx = x的记录在记录的排序顺序中相对较近(例如,保证它位于该顺序的前1000条记录中的某处)

我有两个问题:

  1. 我是否可以认为这是一个有效的查询,还是应该在nidx列中添加索引?
  2. 一个问题的答案是否取决于特定的RDBMS(因此MysqL,Postgresql,MSsqlsqlite等可能有所不同)?如果可以,对于MysqL来说情况如何?

解决方法

排序在过滤后应用。 ORDER BY子句在这种情况下无济于事。同样,除非您在表上有明确的约束条件指示值将是接近的,否则优化器不会知道该值,也将无济于事。

如果您无法/不会在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