在某些情况下语句缺失索引之间

时间:2011-10-31 14:51:03

标签: mysql query-optimization

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

例如:

1112203488

我的表格如下:

| sATON | eATON |信息|

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

所以我的SQL如下:

SELECT * 
FROM  `data2` 
FORCE INDEX ( s, e ) 
WHERE 1112203488
BETWEEN  `sATON` 
AND  `eATON`;

因此,通常在使用索引时,查询将花费几乎零时间(0.02)。但是,有时看起来MySQL中的表统计信息正在决定进行全表扫描,尽管我强迫在SQL中使用索引。这是一个巨大的性能损失,因为它需要0.02到120秒的查询。

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

67372289
134744072

缓慢的那些:

1112203488
1348203839

如果它有助于索引使用BTREE。

2 个答案:

答案 0 :(得分:1)

如果任何此类查询将返回最多一行,则表示(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
      )

甚至是这个(只需要使用一个索引,sATON):

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

答案 1 :(得分:1)

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

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

使用绑定变量有以下几个目的:

  1. 消除SQL injection
  2. 的风险
  3. 允许数据库重用已编译的SQL语句
  4. 减少不同问题的数量,更好地利用数据库缓存最近使用的问题
  5. 我主要使用Oracle,所以我不确定mysql的有效2和3是多少。

    如果您想知道如何使用它们,只需google for:mysql bind variable example +your programming language