我有一个庞大的数字数据库,我正在寻找它们之间的匹配:
例如:
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。
答案 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建议的解决方案,它应该能够有效地使用这两个索引。
使用绑定变量有以下几个目的:
我主要使用Oracle,所以我不确定mysql的有效2和3是多少。
如果您想知道如何使用它们,只需google for:mysql bind variable example +your programming language