我正在寻找一种方法来确保SELECT查询在给定的最大时间内返回,并在必要时返回部分结果。
以下是我所面临的更详细的问题:
我有很多表看起来像这样:
table name: user_1
date | object_id | row_id
2015-05-13 | 0 | 1
2015-05-13 | 0 | 2
2015-05-14 | 0 | 3
...
2015-06-15 | 0 | 5000001
2015-06-15 | 0 | 5000002
2015-06-15 | 0 | 5000003
2015-06-16 | 123 | 5000004
2015-06-17 | 435 | 5000005
我有user_1
到user_1000
的类似表格。
row_id
上有一个PRIMARY INDEX,date
上有一个INDEX。
我们正处于迁移过程中。所有新数据(2015-06-16之后)都使用非零object_id
创建,过去的数据可以迁移,也可以不迁移。如果2015-06-16之前的任何行具有非零object_id
字段,则会迁移表。
我尝试通过以下请求了解表格的数据是否已迁移:
SELECT * FROM user_1 WHERE date < 2015-06-16 AND object_id > 0 LIMIT 1
它按预期工作。迁移数据时速度很快(引擎快速找到与WHERE子句匹配的行)。数据未迁移时速度很慢(引擎解析所有行以确保没有与WHERE子句匹配)。 object_id
列上没有索引,我无法创建索引。
为了加快我试图仅读取第一行的内容:
SELECT object_id FROM user_1 ORDER BY date ASC LIMIT 1
我在PHP代码中测试object_id > 0
。它总是很快,而且很棒。但是我可能会有错误的否定结果,因为迁移过程有时无法迁移一行,在这种情况下object_id
仍为0。
我的第三次尝试是在给定的时间范围内搜索,以降低误报的可能性。
SELECT * FROM user_1 WHERE object_id > 0 AND date BETWEEN 2015-06-01 AND 2015-06-15 LIMIT 1
问题是我不确定在所有user_*
表的这些日期之间是否有行。在表仍然迁移的情况下,此日期范围内可能没有行。如果我设置了较大的日期范围,则查询速度较慢。
所以,回到我的问题,我想做一个请求,搜索匹配我的WHERE子句的行,最多让我们说100ms。如果它在3ms内找到迁移的行,则查询会快速返回,否则我会减少假阴性情况,但我只花费100ms进行该尝试。
我知道我可以使用MySQL 5.7设置超时,但我仍然坚持使用MySQL 5.5。表引擎是TokuDB。还有带有PDO的PHP 5.5。类似于ElasticSearch's timeout的解决方案将是完美的。
感谢您的任何建议。
答案 0 :(得分:0)
我找到了一种通过执行子请求来控制请求执行时间的方法。我不知道它是否是最好的方法,但我可以通过修改内部LIMIT
值来间接推断执行时间。
设置LIMIT 10000
比LIMIT 100000
快,但100000减少假阴性案例。
旧请求:
SELECT * FROM user_1 WHERE date < 2015-06-16 AND object_id > 0 LIMIT 1
变为
SELECT * FROM (
SELECT object_id FROM user_1
WHERE date < 2015-06-16
LIMIT 100000
) s
WHERE s.object_id > 0
LIMIT 1