0

私は比較的複雑なクエリを持っています。ここにフィドルがあります: http://sqlfiddle.com/#!2/65c66/12/0

SELECT p.title AS title_1,
       p2.title AS title_2,
       COUNT(DISTINCT s.signature_id) AS num_signers,
       group_concat(DISTINCT s.signature_id separator ' ') AS signers
FROM wtp_data_petitions p
JOIN wtp_data_petitions p2 ON (p.serial > p2.serial)
JOIN wtp_data_signatures s
GROUP BY s.signature_id
HAVING sum(s.petition_id=p.id)
AND sum(s.petition_id=p2.id);

これがEXPLAINです(sqlfiddleではなく、実際のデータセットにある行数を示しています):

+----+-------------+-------+-------+---------------+--------------+---------+------+----------+---------------------------------+
| id | select_type | table | type  | possible_keys | key          | key_len | ref  | rows     | Extra                           |
+----+-------------+-------+-------+---------------+--------------+---------+------+----------+---------------------------------+
|  1 | SIMPLE      | p     | ALL   | PRIMARY       | NULL         | NULL    | NULL |     1727 | Using temporary; Using filesort |
|  1 | SIMPLE      | p2    | ALL   | PRIMARY       | NULL         | NULL    | NULL |     1727 | Using where; Using join buffer  |
|  1 | SIMPLE      | s     | index | NULL          | signature_id | 105     | NULL | 12943894 | Using index; Using join buffer  |
+----+-------------+-------+-------+---------------+--------------+---------+------+----------+---------------------------------+

この時点で、クエリはファイルソートで非常に多くのディスク領域を使用しているため、エラーが発生する前にクエリが正常に完了するのをまだ確認していません。これをより迅速に、またはより効率的に行うために実行できる最適化はありますか?

ありがとう!

4

2 に答える 2

1

はい。できることの 1 つは、結合条件をon節に移動することです。

SELECT p.title AS title_1,
       p2.title AS title_2,
       COUNT(DISTINCT s.signature_id) AS num_signers,
       group_concat(DISTINCT s.signature_id separator ' ') AS signers
FROM wtp_data_petitions p
JOIN wtp_data_petitions p2 ON (p.serial > p2.serial)
JOIN wtp_data_signatures s on s.petition_id=p.id or s.petition_id=p2.id
GROUP BY s.signature_id;

group byまた、オンにする必要があると思いますp.title, p2.title

SELECT p.title AS title_1,
       p2.title AS title_2,
       COUNT(DISTINCT s.signature_id) AS num_signers,
       group_concat(DISTINCT s.signature_id separator ' ') AS signers
FROM wtp_data_petitions p
JOIN wtp_data_petitions p2 ON (p.serial > p2.serial)
JOIN wtp_data_signatures s on s.petition_id=p.id or s.petition_id=p2.id
GROUP BY p.title, p2.title;

しかし、なぜ2番目の結合を行うのですか? クエリが何をしているのかわかりません。

編集:

あなたが望む基本的なクエリは次のとおりだと思います:

select s1.petition_id, s2.petition_id, count(*) as numsignatures, 
       group_concat(s1.signature_id) as signatures  
from wtp_data_signatures s1 join
     wtp.data_signatures s2
     on s1.signature_id = s2.signature_id and
        s1.petition_id < s2.petition_id
group by s1.petition_id, s2.petition_id;

これを拡張して、請願情報を含めることができます。

select p1.title as title_1, p2.title as title_2,
       s1.petition_id, s2.petition_id, count(*) as numsignatures, 
       group_concat(s1.signature_id) as signatures  
from wtp_data_signatures s1 join
     wtp.data_signatures s2
     on s1.signature_id = s2.signature_id and
        s1.petition_id < s2.petition_id join
     wtp_data_petitions p1
     on p1.id = s1.petition_id join
     wtp_data_petitions p2
     ON p2.id = s2.petition_id 
group by s1.petition_id, s2.petition_id;
于 2013-07-26T02:21:02.777 に答える