0

我有这个查询,我需要在必须解析与另一个表中的另一个字段匹配的字段信息的地方执行此查询,然后在多个表中冲洗并重复,最后这会导致返回所需的行。

问题是,我怎样才能加快速度……它返回了数十万行,并且由于查询导致崩溃,因此对于我的客户在他们的管理部分中的工作不太好。

这是查询:

SELECT DISTINCT t1.CU_ship_name1, t1.CU_ship_name2, t1.CU_email 
FROM (
      SELECT CU_id, CU_ship_name1, CU_ship_name2, CU_email
      FROM customers 
      WHERE CU_solicit=1 
      AND CU_cdate >=".$startDate." 
      AND CU_cdate <=".$endDate."
     )AS t1
INNER JOIN orders AS t2 ON t1.CU_id = t2.O_cid 
INNER JOIN item AS t3 ON t2.O_ref = t3.I_oref 
INNER JOIN product AS t4 ON t3.I_pid = t4.P_id 
INNER JOIN (
            SELECT C_id FROM category WHERE C_store_type =1
           ) AS t5 ON t4.P_cat = t5.C_id

'customers'、'orders'、'item' 表每月更新数万行新行,而 'product' 表每月至少接收 100 行新行。

我唯一能想到的就是创建一个保存此信息的新表(这不是一个理想的解决方案),并为这些表添加一个索引。我担心索引,因为这些表获得了如此大量的新数据,但我愿意尝试(总是可以撤消它对吗?)。但是我不相信索引会自行解决问题。

更新:我现在正在使用此查询并获得更快的结果,索引所有 WHERE 和 JOIN ON 行根本没有多大帮助......我不知道为什么。

删除子查询:

对我的查询速度也产生了灾难性的影响,从下面查询的 3-4 秒到具有相同参数的 151 秒。

SELECT DISTINCT t1.CU_ship_name1, t1.CU_ship_name2, t1.CU_email 
FROM customers AS t1 
WHERE t1.CU_solicit=1 
AND t1.CU_cdate>= 20100725000000
AND t1.CU_cdate<= 20100801000000
AND EXISTS(
    SELECT NULL FROM orders AS t2
    INNER JOIN item AS t3 ON t2.O_ref = t3.I_oref 
    INNER JOIN product AS t4 ON t3.I_pid = t4.P_id 
    INNER JOIN (
        SELECT C_id 
        FROM category 
        WHERE C_store_type = 2
    ) AS t5 ON t4.P_cat = t5.C_id
    WHERE t1.CU_id = t2.O_cid);

没关系,我把它们改成了普通的连接,没有子查询,这件事在所有事情发生后现在正在迅速减轻。这是现在的查询:

SELECT DISTINCT t1.CU_ship_name1, t1.CU_ship_name2, t1.CU_email 
FROM customers AS t1 
JOIN orders AS t2 ON t1.CU_id = t2.O_cid 
JOIN item AS t3 ON t2.O_ref = t3.I_oref 
JOIN product AS t4 ON t3.I_pid = t4.P_id 
JOIN category AS t5 ON t4.P_cat = t5.C_id 
WHERE t1.CU_solicit =1 
AND t1.CU_cdate >=20100425000000
AND t1.CU_cdate <=20100801000000
AND t5.C_store_type =2
4

2 回答 2

2

我会尝试两件事:

1) 在 ON 和 WHERE 子句中使用的列上添加索引

2) 通过将子查询重写为普通的 JOIN 和 WHERE 条件来消除子查询

只有在您完成这些并发现您仍然遇到问题后,您才应该考虑其他选择。

除了不必要的子查询之外,这看起来确实是一个非常简单的查询。除非您没有定义索引,您的 MySQL 可用内存太少,或者您为可用资源配置的 MySQL 服务器本身非常糟糕,否则您不会期望它即使有数百万行也会变慢。

一个月新一万行不算什么。你每隔几分钟就会换一个新行。在决定要定义哪些索引时,这甚至都不是考虑因素。廉价服务器上的 MySQL每秒可以处理数百次插入。

于 2010-11-18T23:45:53.670 回答
1

我会在你的 where Criteria 以及你的 ON 语句中索引列。索引将立即解决您的崩溃问题,并且可能不会显着降低您的修改操作。每月数万行实际上并没有那么多行——除非你的数据库在一台薄弱的机器上。

此外,我会考虑完全删除子查询。它们通常会降低 sql server 的性能。您可能还想考虑将查询移动到存储过程中,以便服务器有机会缓存​​其执行计划。

于 2010-11-18T23:47:15.790 回答