最近の質問で、StevieG はピボット テーブルに関する問題を解決する方法を教えてくれました。新しい問題は、ピボット テーブルでいくつかの条件を確認する必要があることです。最後のクエリを見てみましょう:
SELECT
c.id,
GROUP_CONCAT(if(d.name = 'p1', d.value, NULL)) AS 'p1',
GROUP_CONCAT(if(d.name = 'p2', d.value, NULL)) AS 'p2',
GROUP_CONCAT(if(d.name = 'p3', d.value, NULL)) AS 'p3',
GROUP_CONCAT(if(d.name = 'p4', d.value, NULL)) AS 'p4',
GROUP_CONCAT(if(d.name = 'p5', d.value, NULL)) AS 'p5',
GROUP_CONCAT(if(d.name = 'p6', d.value, NULL)) AS 'p6'
FROM container c
JOIN data d ON c.id = d.container
GROUP BY c.id
明らかに、WHERE 句を追加することはできません (たとえば、p5>30 かどうかを確認したい場合)。この問題を解決する 2 つの方法を見つけました。まず、派生テーブルでこれを変換します。
SELECT * FROM (
SELECT
c.id,
GROUP_CONCAT(if(d.name = 'p1', d.value, NULL)) AS 'p1',
GROUP_CONCAT(if(d.name = 'p2', d.value, NULL)) AS 'p2',
GROUP_CONCAT(if(d.name = 'p3', d.value, NULL)) AS 'p3',
GROUP_CONCAT(if(d.name = 'p4', d.value, NULL)) AS 'p4',
GROUP_CONCAT(if(d.name = 'p5', d.value, NULL)) AS 'p5',
GROUP_CONCAT(if(d.name = 'p6', d.value, NULL)) AS 'p6'
FROM container c
JOIN data d ON c.id = d.container
GROUP BY c.id
) WHERE p5>30
そして、私が見つけたもう1つの方法は、HAVING句を追加することです:
SELECT
c.id,
GROUP_CONCAT(if(d.name = 'p1', d.value, NULL)) AS 'p1',
GROUP_CONCAT(if(d.name = 'p2', d.value, NULL)) AS 'p2',
GROUP_CONCAT(if(d.name = 'p3', d.value, NULL)) AS 'p3',
GROUP_CONCAT(if(d.name = 'p4', d.value, NULL)) AS 'p4',
GROUP_CONCAT(if(d.name = 'p5', d.value, NULL)) AS 'p5',
GROUP_CONCAT(if(d.name = 'p6', d.value, NULL)) AS 'p6'
FROM container c
JOIN data d ON c.id = d.container
GROUP BY c.id
HAVING p5>30
問題はパフォーマンスについてです。私は 50,000 エントリのテスト データベースを使用していますが、本番環境では 100 万に達する可能性があります。最初の文 (p5>30 をチェックしていないもの) は、私の開発用コンピューター (キャッシュなし) で 1000 文を実行するのに 0'60 秒かかりますが、2 番目と 3 番目の文は同じことを行うのに 5 分以上かかります。
データ インデックスを使用しない暗黙的な派生テーブルの生成があることは理解していますが、これを最適化するためのオプションは何ですか?