MySQL上的特定查询优化

时间:2015-11-13 12:35:14

标签: mysql query-optimization

我有MySQL DB(版本5.1.x)的表格,名称为表格。它的列是: id double_col_index1 double_col_index2 标记 col_index_1 a_date_col < / strong>, col_index_2 col_index_3 ,包含以下索引:

  • double_col_index1 上的单个索引和 double_col_index2
  • col_index_1
  • 的索引
  • col_index_2
  • 的索引
  • col_index_3
  • 的索引

现在,我有以下查询:


UPDATE `table` t1 INNER JOIN 
(SELECT t2.id FROM `table` t2 
    WHERE t2.double_col_index1 = 'fake_value1' 
        AND t2.double_col_index2 = 'fake_value2' 
        AND flag = 'true' 
        AND (col_index_1 = '' OR a_date_col < '1920-11-10 00:00:00') 
        AND 
        (SELECT count(t3.id) FROM `table` t3 
            WHERE t3.double_col_index1 = 'fake_value1' 
            AND t3.double_col_index2 = 'fake_value2' 
            AND t3.col_index_2 = t2.col_index_2 
            AND t3.col_index_3 = 'fake_col_index_3_1') > 0 
        AND 
        (SELECT count(t4.id) FROM `table` t4 
            WHERE t4.double_col_index1 = 'fake_value1' 
            AND t4.double_col_index2 = 'fake_value2' 
            AND t4.col_index_2 = t2.col_index_2 
            AND t4.col_index_3 = 'fake_col_index_3_2') > 0)  tbl 
ON t1.id = tbl.id SET col_index_1 = 'fake_value';

问题:我需要改进此查询,以便在可能的情况下提供更好的性能。有人对此有任何建议吗?

一个想法是使用而不是INNER JOINt1.id in (...。你对此有何建议?

1 个答案:

答案 0 :(得分:1)

联接的基本思想是按如下方式进行。

UPDATE `table` t1 
INNER JOIN 
(
    SELECT t2.id 
    FROM `table` t2 
    INNER JOIN
    (
        SELECT DISTINCT col_index_2
        FROM `table`  
        WHERE double_col_index1 = 'fake_value1' 
        AND double_col_index2 = 'fake_value2' 
        AND col_index_3 = 'fake_col_index_3_1'
    ) t3 
    ON t3.col_index_2 = t2.col_index_2 
    INNER JOIN
    (
        SELECT DISTINCT col_index_2
        FROM `table`  
        WHERE double_col_index1 = 'fake_value1' 
        AND double_col_index2 = 'fake_value2' 
        AND col_index_3 = 'fake_col_index_3_2'
    ) t4
    ON t4.col_index_2 = t2.col_index_2 
    WHERE t2.double_col_index1 = 'fake_value1' 
    AND t2.double_col_index2 = 'fake_value2' 
    AND flag = 'true' 
    AND (col_index_1 = '' OR a_date_col < '1920-11-10 00:00:00') 
)  tbl 
ON t1.id = tbl.id 
SET col_index_1 = 'fake_value';

这可能会快得多,但取决于很多因素。 MySQL不会使用索引来加入子查询。

然而,MySQL(以及您现有的查询)在MySQL

中存在很大问题

http://dev.mysql.com/doc/refman/5.7/en/update.html

目前,您无法更新表并从子查询中的同一个表中进行选择。

通过对子查询进行查询

,可以解决这个问题