テーブル設計について。
DBから集計して、このような表を出しているのですが、
現在、レコードが10万件ほどあり、集計のクエリが終わるまで7秒近くかかっています。
※以下、タブ区切りにしてありますので、エディタなどに貼り付けて頂くと見やすいと思います。
【表】
質問グループ質問タグ答えOK数答えNG数
Aa21
Ab20
Ba12
【DB】
テーブル:test
idanswergrouptag
1OKAa
2NGAa
3OKAa
4OKAb
5OKAb
6OKBa
7NGBa
8NGBa
【クエリ】
SELECT group, tag,
SUM(CASE WHEN answer='ok' THEN 1 ELSE 0 END) AS ok,
SUM(CASE WHEN answer='ng' THEN 1 ELSE 0 END) AS ng
FROM test
GROUP BY group, tag;
※「id」をprimaryキー、「group、tag、answer」をまとめてuniqueとしてインデックスを貼ってます
ok数とng数の集計に時間がかかってしまっているのですが、
他に良い方法があれば教えて下さい。
また、そもそものテーブル構成を以下のようにすればいいのでは?
とも思ったのですが、どうなんでしょうか?
この形に変えると、集計は一瞬で終わるはずなのですが、
ok と ngを別カラムにするという考え方がしっくりきません。
テーブル構成の考え方としてどうなのか知りたいです。
下のようにすると、okカラムとngカラムの片方にしか値は入らなくなってしまうので、
それだったら最初の構成のように、answerカラムにokかngのどちらかが入るといった方が好ましいのかなとも思い・・
それと今回はたまたまok と ngの固定2つですが、複数になるような場合もあると思うのです。
テーブル:test
idgrouptagokng
1Aa1NULL
2AaNULL1
3Aa1NULL
4Ab1NULL
5Ab1NULL
6Ba1NULL
7BaNULL1
8BaNULL1
SELECT group, tag, sum(ok), sum(ng)
FROM test
GROUP BY group, tag;
ご教示下さい。
No.2ベストアンサー
- 回答日時:
>「group、tag、answer」をまとめてuniqueとしてインデックスを貼ってます
ごめんなさい、意味不明なところがあります
uniqueはただの入力制限でindexは高速化処理ですよ。
unique”として”インデックスは貼れません。
uniqueしか貼っていないなら早くはならないと思いますが・・
とりあえず
alter table test add index(`answer`,`group`,`tag`);
してみてください
回答遅くなり申し訳ありません。
「group、tag、answer」をuniqueとしてindex貼っていたのがよくなかったです。
この点勘違いしておりました。
再度、「group、tag、answer」に対して複合インデックスを貼り直したところ速くなりました。
ありがとうございました。
No.6
- 回答日時:
このクエリだと、EXPLAINでtype=index、Extra=Using indexの状態であれば、それ以上高速化できないように思います。
手元のマシンで試してみましたが、26万件程度のデータで0.23秒でした。7秒もかかるということは、他に原因があるのかも知れません。(ディスクI/Oが発生しているのかも知れませんので、バッファの調整をおすすめします。)No.5
- 回答日時:
#4さんの言うとおり、uniqueはインデックス対象でした。
すみません実際のところ今回の場合uniqueではないので、意味がないと言いたかったんですが
蛇足でしたね
No.4
- 回答日時:
ちょっと集中力がない状態なのですが、取りあえず追記。
> uniqueしか貼っていないなら早くはならないと思いますが・・
ん?
表定義でuniqueで一意性制約を指定すると、その実装のためにMySQLでも内部的にインデクスが作成されますが、違う意味かな。。。create unique indexでも定義できますし。
もちろん、このユニークチェックのためのインデクスは、検索の性能を出すためにも活用できます。
提示された情報だけから見ると、母体データの全行、全列を見ることになるので、オプティマイザがどう動いているのか。グループ化のためにソートが必要だし。
他にもっとたくさん列があるとか、母体データから一部分の抽出だったらとか。
昇順、降順を混在された複合キーだと、MySQLは内部的に全部昇順にするいった制限があり、昇順、降順を混在したソートするような指定をするとインデクスを使ってくれないといったケースもありますが、詳しい提示がないのでその辺は省略します。
EXPLAINの結果を見てもらったり、もっと詳しい具体的な定義内容を提示してくれるとかあれば、また別のアドバイスができるかも知れませんが、取りあえず今回はここまで。
No.3
- 回答日時:
ちなみに・・・
サブクエリをつかってこんな風にもできますが、効率は変わりません
SELECT `group`, tag, sum(answer='ok')*counta as ok,sum(answer='ng')*counta as ng
from (SELECT `group`, tag,answer,count(*) as counta FROM test GROUP BY `group`, tag,answer
) as sub
GROUP BY `group`, tag
No.1
- 回答日時:
MySQLのバージョンを、MySQL 4.1、MySQL 5.0、MySQL 5.1といったレベルまで、最低限提示するようにしてください。
EXPLAINを実行して、どういう処理方法になっているか結果を見てみましたか?
http://dev.mysql.com/doc/refman/5.1/ja/explain.h …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP 【PHP/MySQL】コード上で生成したクエリを基に集計クエリを作りたい 1 2022/07/28 15:06
- MySQL SQLです。下記の問合せを行うクエリを、PhpMyAdminで作成して実行せよ。 「昨年の各月の総降 1 2023/07/01 00:32
- Excel(エクセル) 【Excel関数、count系】どなたか教示下さると助かります。 Excelでシフトを管理しており、 2 2022/07/09 06:34
- MySQL PHPとMySQLを使った掲示板の作り方 1 2022/06/02 13:00
- Access(アクセス) アクセス テーブルの空白を変数に置換するボタンが作りたい 4 2022/07/08 11:19
- MySQL `picture` varchar(255) のコマンドで間違いないでしょうか? 1 2022/11/21 04:08
- PHP クエリObjectをforeachで回す時に、次のレコードへ移動せずに次のレコードを取得したい 2 2022/07/28 15:29
- MySQL うまくいきません教えてくださいお願いしますSQLです。クエリ構文です。 1 2023/07/07 12:39
- MySQL SQLです。こんな感じですか?あってますか? うまくいきません教えてくださいお願いします 1 2023/07/08 15:27
- Oracle SQLについて教えて下さい。 主キーを持ったカラムを主キーの機能を持たせたまま カンマ区切りで文字列 1 2023/03/27 22:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ユニーク制約とユニークインデ...
-
(初心者)MySQLやmaraDBで、crea...
-
一部のカラムでdistinctし全て...
-
LIKEの右側にカラムを指定でき...
-
INDIRECT関数の代替方法は?
-
DBの定義のサイズを大きくし過...
-
now()かCURRENT_TIMESTAMPか
-
GREATESTで NULLをスルーする方...
-
group byで最後のレコードを抽...
-
最大2147483647なのに何故int(1...
-
DBエラーの意味
-
テーブルの列数を調べたい
-
SELECT文で、指定カラム以外の...
-
select * での表示が崩れる?
-
時間範囲が重複したレコードを...
-
mysqlで50音順にorder byしたい。
-
mySQL プライマリーキーのカラ...
-
DB2のBLOB型カラムに格納された...
-
WHEREなどの条件が多い場合、ど...
-
【Transact-sql】 where条件、i...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ユニーク制約とユニークインデ...
-
オートインクリメントについて
-
MySQLのKey属性「MUL」について
-
複数カラム検索で、LIKE "%検索...
-
大量の項目を対象に効率的に検...
-
SQL Server Management Studio...
-
インデックスについて
-
UPDATEつてインデックス貼って...
-
MySQLのインデックスについて
-
1000件以下の場合はカラム数に...
-
MySqlでのデータソートについて
-
文字検索 (LIKE)を使った場合
-
インデックス作成について
-
テーブル設計について。
-
複合インデックスの設定に関して
-
インデックスを張るべき項目に...
-
検索エンジン検索結果から削除...
-
INDIRECT関数の代替方法は?
-
DBの定義のサイズを大きくし過...
-
SELECT文で、指定カラム以外の...
おすすめ情報