- ベストアンサー
クエリの遅さの原因
下記のクエリーをそれぞれ試してみたところ、圧倒的に下の方が遅くなってしまいました。 $rs = mysql_query("select * from A INNER JOIN B ON B.cat = A.id order by B.id desc LIMIT 1, 10 ;",$con); $rs = mysql_query("select * from A INNER JOIN B ON B.cat = A.id where B.name is not null group by B.area order by B.id desc LIMIT 1, 10 ;",$con); where B.name is not null group by B.area この処理はそれほど負荷が掛かってしまうのでしょうか。 他に良い書き方(方法)がありましたら教えてください。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
データが何件あるのか分かりませんが、「B.name is not null」という検索条件があり、さらに「group by B.area」でソートが行われる訳ですから、普通に考えて後者の方が「重い」でしょう。 それ以前の問題として、後者のSQLは「間違った使い方」をしていると思います。 標準SQLや主要なRDBMSでは、group by指定時、selectの選択リストで指定できるのは、 (1)group byで指定した列 (2)sumやcount、maxなどの集合(集計)関数 (3)定数 だけです。 MySQL以外のRDBMSでは、文法エラーになります。 しかし、MySQLはこの制限に拡張仕様を持っていて、「group byにより結果が一意になるなら、その列を指定してもよい。しかし、一意にならないなら結果は保証しない」としています。 <例> select c1,max(c2),c3 from t1 group by c1 c3列を指定することは、標準SQLに反する。また、主要なRDBMSではgroup byとselectの選択リストの指定の矛盾でエラーになる。 MySQLでは、c1でグループ化することで、c3も一意になるなら指定してよい。そうでないなら、結果は保証されない。 (エラーにならないので注意が必要) >他に良い書き方(方法)がありましたら教えてください。 何をやりたいのか具体的な説明なしに、アドバイスのしようがありません。また、MySQLのバージョンも書きましょう。
その他の回答 (2)
- yambejp
- ベストアンサー率51% (3827/7415)
>A・Bテーブルを結合して、Bのareaカラムの重複データを除外した上で、 >A・Bテーブルから全てのデータを取得した もしそうであればSQLの書き方が違いますね Bのareaに重複データは最初からあるのですよね? areaが重複する場合、その他のフィールド値は同じなのでしょうか? 違う場合はどのデータが抽出されることを期待しているのでしょうか? やり方としてはまずBのareaを一元化してからそのデータをもとに AにJOINするということになります また、正規化されているかどうかもわかりづらいので、 A.idとB.catは1対1なのかn対nのなのかそのあたりも踏まえた質問が 望ましいです
お礼
はい、Bのareaに重複データがありまして、その他のフィールド値は異なります。 また抽出したいデータはAとBの全データになります。 >Bのareaを一元化してからそのデータをもとにAにJOINするということになります これを実際にSQLで記述(?)するとどのようになるのでしょうか? A.idとB.catは1対1になります。 正規化という意味も分からない知識レベルなので質問に必要な情報が欠けていて申し訳ありません。
- yambejp
- ベストアンサー率51% (3827/7415)
ちょっとめんどうなので実証していませんが AにBをINNER JOIN しているのにB.nameのnullをwhere句で検証しているのは なぜ? 通常AにBをLEFT JOINするとBにnullがのこる可能背はあるとおもうけど・・・ もしB.nameに最初からNULLがあるならWhereするまえにINNER JOIN ON の条件にANDでつないでみてはどうでしょうか? それと外部結合したテーブルの項目でgroup by するのは非効率のような 気が・・・設計段階の問題があるかも
お礼
私の知識のなさに加えて、おっしゃるとおり、設計段階の問題が大きいみたいです。どうもありがとうございました。
補足
SQLの間違った使い方をご指摘して頂いてありがとうございました。 まったく知りませんでした。 バージョンはMySQL3.23です。 やりたいことは、A・Bテーブルを結合して、Bのareaカラムの重複データを除外した上で、A・Bテーブルから全てのデータを取得したいと思っています。 こういうことは可能でしょうか?