Mysql SQL查询性能-单个记录,按非索引列过滤,按索引列排序,记录在排序的记录序列中是闭合的

Mysql SQL查询性能-单个记录,按非索引列过滤,按索引列排序,记录在排序的记录序列中是闭合的,mysql,sql,database,database-performance,Mysql,Sql,Database,Database Performance,我有以下(我的)SQL查询: 从表中选择*,其中nidx=x ORDER BY id DESC LIMIT 1 根据以下假设: id是一个索引字段 nidx是一个非索引字段(假设它有一个数字类型) x是一个常数 nidx=x的记录在有序的记录序列中相对较近(假设它保证位于顺序中的前1000条记录中的某个位置) 我有两个问题: 我可以假设这是一个有效的查询,还是应该向nidx列添加索引 第一个问题的答案是否取决于特定的RDBMS(因此MySQL、PostgreSQL、MSSQL、SQLite

我有以下(我的)SQL查询:

从表中选择*,其中nidx=x ORDER BY id DESC LIMIT 1
根据以下假设:

  • id
    是一个索引字段
  • nidx
    是一个非索引字段(假设它有一个数字类型)
  • x
    是一个常数
  • nidx=x的记录在有序的记录序列中相对较近(假设它保证位于顺序中的前1000条记录中的某个位置)
我有两个问题:

  • 我可以假设这是一个有效的查询,还是应该向
    nidx
    列添加索引
  • 第一个问题的答案是否取决于特定的RDBMS(因此MySQL、PostgreSQL、MSSQL、SQLite等可能会有所不同)?如果是,MySQL的情况如何

  • 过滤后应用排序。在这种情况下,
    orderby
    子句对搜索没有帮助。同样,除非你在表格上有一些明确的约束,表明数值将接近,否则优化者不知道这一点,也不会有帮助

    如果您不能/不会在
    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
    来准确了解按什么顺序执行的操作


    然而,总的来说,这是一个黑客,不要太依赖它。最好修复索引

    • 这是对所有平台的建议

    只需添加索引。:)

    考虑到记录的数量,索引将是首选。 MySQL中的示例:

    ALTER TABLE  table ADD INDEX nidx_index (nidx)
    
    还可以为唯一值创建唯一索引:

    ALTER TABLE  table ADD UNIQUE INDEX nidx_index (nidx)
    

    可以为nidx字段使用索引,但必须记住,这会使更新、插入和删除查询效率更低

    ORDER BY和GROUP BY是sql查询中最严重的惩罚,因为它们是在最后执行的操作。如果没有必要,我会通过

    最后,您可以使用EXPLAIN命令诊断SQL查询

    EXPLAIN SELECT * FROM table WHERE nidx = x ORDER BY id DESC 
    
    下面是一个使用Explain改进查询的小教程

    OP不是问如何添加索引,而是问他们是否真的需要添加索引,或者他们是否可以依赖其他功能和行为。你的答案应该解释他们为什么需要索引,并且他们描述的特性不会改变这一点。正如MatBailie所说。我认为关键的假设是记录的顺序接近。您假设
    nidx
    是唯一的。可能是
    ndix=x
    产生多行,然后
    orderbyid LIMIT 1
    选择id最低的一行。你的假设可能是正确的,但至少应该被陈述或质疑。