Mysql 在某些情况下,语句之间缺少索引

Mysql 在某些情况下,语句之间缺少索引,mysql,query-optimization,Mysql,Query Optimization,我有一个庞大的数字数据库,我正在寻找两者之间的匹配: 例如: 1112203488 我的桌子看起来像这样: |萨顿|伊顿|信息| 我在sATON和eATON上有两个索引(名为s和e) 因此,我的SQL如下所示: SELECT * FROM `data2` FORCE INDEX ( s, e ) WHERE 1112203488 BETWEEN `sATON` AND `eATON`; 因此,通常在使用索引时,查询将花费几乎为零的时间(0.02)。然而,有时看起来MySQL中的

我有一个庞大的数字数据库,我正在寻找两者之间的匹配:

例如:

1112203488
我的桌子看起来像这样:

|萨顿|伊顿|信息|

我在sATON和eATON上有两个索引(名为s和e)

因此,我的SQL如下所示:

SELECT * 
FROM  `data2` 
FORCE INDEX ( s, e ) 
WHERE 1112203488
BETWEEN  `sATON` 
AND  `eATON`;
因此,通常在使用索引时,查询将花费几乎为零的时间(0.02)。然而,有时看起来MySQL中的表stats决定执行完整的表扫描,尽管我强制在SQL中使用索引。这是一个巨大的性能损失,因为它将查询时间从0.02秒缩短到120秒

以下是一些快速运行的示例(使用索引):

慢的是:

1112203488
1348203839

如果索引使用BTREE有帮助。

如果任何此类查询将返回最多一行,这意味着
(sATON,eATON)
范围不重叠

因此,只有当范围不重叠时,您才可以使用此查询:

SELECT * 
FROM data2 
WHERE sATON = 
      ( SELECT MAX(sATON)
        FROM data2 
        WHERE sATON <= 1112203488
      )
  AND eATON = 
      ( SELECT MIN(eATON)
        FROM data2 
        WHERE eATON >= 1112203488
      )

正如ypercube所指出的,当前查询只能使用一个索引。 从您的执行计划中,我可以看到它使用了
s
索引,这意味着它扫描值大于
sAton
的所有行。对于高值,这将是几乎所有的值,使其与全表扫描一样低效

我会选择ypercubes建议的解决方案,它应该能够有效地使用这两个索引

使用绑定变量有多种用途:

  • 消除风险
  • 允许数据库重用已编译的SQL语句
  • 减少不同问题的数量,更好地利用datbase缓存处理最近使用的问题
  • 我主要与Oracle合作,所以我不确定2和3对mysql的有效性


    如果您想知道如何使用它们,只需通过谷歌搜索:
    mysql绑定变量示例+您的编程语言

    慢速查询返回多少行(占表的百分比),快速查询返回多少行(占表的百分比)?表格统计数据是否准确且最新?这两个索引不能同时使用。要么是一个,要么是另一个。@MikeChristensen所有查询都将返回一个,统计数据是最新的。是否对常量使用绑定变量?您希望这样做,因为这样做会阻止优化人员根据该值选择另一个执行计划。你检查过执行计划了吗?@KlasLindbäck,对不起,我不熟悉bind变量。我可以得到一些解释绑定变量理论的链接吗。
    SELECT * 
    FROM data2 
    WHERE sATON = 
          ( SELECT MAX(sATON)
            FROM data2 
            WHERE sATON <= 1112203488
          )
      AND eATON = 
          ( SELECT MIN(eATON)
            FROM data2 
            WHERE eATON >= 1112203488
          )
    
    SELECT * 
    FROM data2 
    WHERE sATON = 
          ( SELECT MAX(sATON)
            FROM data2 
            WHERE sATON <= 1112203488
          )
      AND eATON >= 1112203488