比较两个非常相似的表中包含大量数据的所有单个记录

时间:2013-11-21 16:21:15

标签: php mysql sql cakephp

我正在开发一种用于增强部分回归测试过程的工具。

我需要实现的目标:

我有两张表,大约有7千条记录。一个是来自生产的快照,另一个代表与更新后将实现的完全相同的记录。

每条记录包含50-200个不同长度的字段。这些字段中的两个(field_1和field_2)用作区分记录的标识符。字段1用于记录从生产到记录的更新,字段2用于标识消息的形式。

对于来自制作的记录,始终只有一个记录具有相等的field_1和field_2值。

我想编写一个查询或代码(最多几秒钟内)以下列或类似的形式返回一个数组:

Array
(
    [0] => Array
        (
            [Production] => Array
                (
                    [id] => 83
                    [field1] => value1
                    [field2] => value2
                    [field3] => differing_val
                    [field4] => value3
                      .....
                )

            [Update] => Array
                (
                    [id] => 1
                    [field1] => value1
                    [field2] => value2
                    [field3] => some_other_different_val
                    [field4] => value3
                      .....
                )

        )
)

问题:

  1. 我试图抓住所有记录并动态构建(10分钟后执行甚至没有完成),有一些限制和分页,它更好
  2. 所以我写了这个sql语句,它会为我做部分工作,但即使有一些值的限制,它需要5-7分钟才能完成(而且它只为我完成部分工作)
  3. 这是我的SQL查询:

    SELECT production_records.* FROM production_records
    WHERE production_records.token_2 = 
    (
        SELECT update_records.token_2 FROM update_records
        WHERE 
            update_records.token_1 = production_records.token_1 AND 
            update_records.token_2 = production_records.token_2 AND 
            update_records.token_130 <> production_records.token_130  
    )
    ORDER BY production_records.token_1 DESC
    LIMIT 6
    

    在这里我知道有6个不同,因此限制仍然需要406秒。

    问题:

    你看到了什么,可以用数据或sql来完成更快的运行? 我对sql还不是那么好,所以我猜这就是问题所在。

    我可以完全控制数据,所以我可以改变任何东西,但是没有出现比O(n ^ 2)更好的解决方案。

1 个答案:

答案 0 :(得分:1)

您可能缺少的是您比较的任何内容的索引。例如token_1,token_2,token_130。见http://dev.mysql.com/doc/refman/5.0/en/create-index.html

CREATE INDEX p_1 ON production_records (token_1);
CREATE INDEX p_2 ON production_records (token_2);
CREATE INDEX p_130 ON production_records (token_130);

CREATE INDEX u_1 ON update_records (token_1);
CREATE INDEX u_2 ON update_records (token_2);
CREATE INDEX u_130 ON update_records (token_130);

我还建议重新构建您的查询,并根据其中一条注释中的建议加入表而不是子查询。类似的东西:

SELECT p.* FROM production_records p
LEFT JOIN update_records u
ON u.token_1 = p.token_1 AND u.token_2 = p.token_2 AND u.token_130 <> p.token_130
ORDER BY p.token_1 DESC

相同的查询可以表示为

SELECT p.* FROM production_records p, update_records u
WHERE u.token_1 = p.token_1 AND u.token_2 = p.token_2 AND u.token_130 <> p.token_130
ORDER BY p.token_1 DESC

两个查询都或多或少相同。