使用子查询导致另一个子查询中的WHERE IN(优化)

时间:2012-07-02 07:30:05

标签: mysql optimization

这已经困扰了我一段时间了,作为一个新手,我不确定我应该寻找什么。经过几个小时的谷歌搜索后,我找不到令人满意的答案。

我有一个相对复杂的查询,我已经剥离并简化为:

SELECT field_a1,
       field_a2,
       (SELECT Count(*)
        FROM   table_b
        WHERE  field_b1 IN (SELECT field_x1
                            FROM   table_x) AND field_b2 = 1) AS new_field_1,
       (SELECT Count(*)
        FROM   table_c
        WHERE  field_c1 IN (SELECT field_x1
                            FROM   table_x) AND field_c2 = 2) AS new_field_2,
       (SELECT Count(*)
        FROM   table_d
        WHERE  field_d1 IN (SELECT field_x1
                            FROM   table_x) AND field_d2 = 3) AS new_field_3
FROM   table_a
WHERE  field_a1 IN (SELECT field_x1
                    FROM   table_x)

在原始查询中,我有大约30个new_field_*。一切似乎都很好,我得到了一些非常令人满意的结果(最终结果和表现)。

我的问题是这个查询:

SELECT field_x1
FROM   table_x

重复了很多次(返回的行数为30 *),并且总是用作WHERE IN寻找匹配项的集合。

我的问题:

是否可以只执行一次这个小查询并保留该结果并重复使用它?

我能想到的唯一两件(荒谬的)事情是这样的(想象解决方案):

temp = (SELECT field_x1
        FROM   table_x)
SELECT field_1
FROM   table_1
WHERE  field_1 IN temp

或者在客户端(运行PHP的Web服务器)执行此查询一次,然后使用以下内容将结果附加到将来的查询中:

$IN_Condition = implode(',', $stmt->execute()->fetchAll(PDO::FETCH_NUM));
$sql_query = "SELECT field_1
              FROM   table_1
              WHERE  field_1 IN ($IN_Condition)"

2 个答案:

答案 0 :(得分:1)

有时您不需要对查询进行优化,当引擎看到类似的子查询时,它只获取一次数据。但您可以尝试此查询,看看它是否更快:

SELECT a.field_a1, a.field_a2,
   (SELECT Count(*)
    FROM x
    WHERE x.field_x1 = b.field_b1
      AND b.field_b2 = 1) AS new_field_1,
   ...
FROM table_a, table_b b, ..., -- Query here the tables you need
     (SELECT field_x1
      FROM table_x) x
WHERE field_a1 IN x

你也可以将你的表保存在内存中,并将数据与你的php引擎进行比较,但它比使用db引擎要慢。

编辑:您需要的每个表格都会被查询一次

编辑2:颠倒逻辑!

答案 1 :(得分:1)

尝试使用JOIN子句,例如 -

<强>编辑:

SELECT
  field_a1,
  COUNT(b.field_b1) new_field_1,
  COUNT(c.field_c1) new_field_2,
  COUNT(d.field_d1) new_field_3
FROM
  table_a a
JOIN table_x x
  ON x.field_x1 = a.field_a1
LEFT JOIN table_b b
  ON b.field_b1 = x.field_x1
LEFT JOIN table_c c
  ON c.field_c1 = x.field_x1
LEFT JOIN table_d d
  ON d.field_d1 = x.field_x1
GROUP BY
  a.field_a1