我正在使用MySql表。该表仅包含数值和unix日期值。每行都有一个唯一的id,列包含与db的其他部分相关的ID,总计(如每天的下载量)和插入行的日期。我的查询需要获取每个id组合的最新日期,以获得当天的下载。每个id组合每天插入一行,索引跨越所有ID和日期。
我通过测试发现,在某些情况下执行两个查询以获得我想要的确切行更快。我想对此有第二个意见。
这是一个非常快的场景并使用索引:
SELECT * FROM foo WHERE A = 1 AND B = 1 AND mydate BETWEEN 123456789 AND 134567890 ORDER BY mydate DESC LIMIT 1
(索引是A,B,mydate)
这是一个非常慢并且不使用索引的那个:
SELECT * FROM foo WHERE A IN (1, 2) AND B = 1 AND mydate BETWEEN 123456789 AND 134567890 GROUP BY A, B ORDER BY mydate DESC
这会返回正确的结果但不使用索引并且速度很慢。实际上,这个简单的例子可能会使用索引,但A IN(1,2,3,4,5,6,7,8,....10000) AND B IN (1,2,3,4,5,... 10000)
之类的东西并不是,而且这就是我需要提供的东西。
这是有趣的地方。
以下使用索引并且非常快:
SELECT *, MAX(mydate) FROM foo WHERE A IN (1,2,3,4,5,6,7,8,....10000) AND B IN (1,2,3,4,5,6,7,8,....10000) AND mydate BETWEEN 123456789 AND 134567890 GROUP BY A, B
返回的行包含每个组合的唯一ID组合和mydate
的MAX。但是,为每个组合返回的行不一定是具有相应MAX(mydate)
的行,因此不一定给出该日的正确下载。 MAX
值是该特定组合的正确值,因此我的第二个查询可以是特定的并使用索引。假设A为1,B为1且MAX(mydate)
等于1235555555为特定的id组合,那么我可以执行
SELECT * FROM foo WHERE A = 1 AND B = 1 AND mydate = 1235555555
第二个查询返回我想要的特定行,使用索引,因此很快。
我必须使用php进行foreach
,因此那里有处理开销,但它仍然比尝试让MySQL完成所有工作要快得多。
另一个好处是所有这些简单查询都是作为单独的MySQL进程执行的。
感觉不对,我错过了什么吗?