• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:遅いクエリーを改善するため他の書き方を教えて欲しい)

遅いクエリーの改善方法

yambejpの回答

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

まず文法が変なところから >select i.id AS id,i.name AS iname,i.price AS iprice,v.id AS vid,v.vote AS vvote,SUM(IF(v.vote='10',1,0)) AS totalvote from item AS i LEFT JOIN vote AS v ON i.id=v.id GROUP BY i.id order by totalvote desc; itemについてidはユニークだという前提で、i.idでgroup byしているなら v.voteは不定なのでselectで得ることはできません。 MySQLの特質上エラーにはなりませんが、期待したデータがとれる保証はありません。 それを踏まえて・・・vvoteは省略すると >最高点のみの投票数を合計して、その合計投票数が大きい順に商品をソート select i.id AS id,i.name AS iname,i.price AS iprice,v.id AS vid,,COUNT(v.id) AS totalvote from item AS i LEFT JOIN vote AS v ON i.id=v.id and v.vote='10' GROUP BY i.id order by totalvote desc; みたいな処理の方が軽くなるのでは? なお、itemとvoteのそれぞれのテーブルには適切なインデックスを貼ってください。

astu2006
質問者

補足

アドバイスありがとうございます。 itemのidはPRIMARYキーになっているのですが、PRIMARYでもご指摘のように期待したデータが取れる保証はないのでしょうか。 もし正確なデータを取りたい場合にはテーブルの設計から見直したほうがいいでしょうか。 また、教えて頂いたクエリーを試してみたのですが速度はほとんど変わりませんでした。 これはご指摘の通り文法がおかしいからなのか、それともindexがうまく張られてないからなのか・・・ indexは「itemテーブルのid」と「voteテーブルのid」と「voteテーブルのvote」に作成しているのですがこれでは不十分なのでしょうか。 質問ばかりで申し訳ありません。

関連するQ&A

  • データがない場合のクエリの書き方

    いつもお世話になっております。 MySQLとPHPで開発をしております。 以下のような3つのテーブルがあります。 テーブル:Hp(キー:hid) |hid |name |・・・| +---------------------+ |1  |a_name|・・・| |2  |b_name|・・・| テーブル:items(キー:item_id) |item_id|item|alias|type|・・・| +----------------------------------+ |1   |aa |aaaaa|11 |・・・| |2   |bb |bbbbb|11 |・・・| |3   |cc |ccccc|11 |・・・| |4   |dd |ddddd|22 |・・・| |5   |ee |eeeee|22 |・・・| テーブル:check(キー:hid, item_id ) |hid|item_id|・・・| +-------------------+ |1 |1   |・・・| |1 |2   |・・・| |1 |3   |・・・| |2 |1   |・・・| |2 |3   |・・・| |2 |5   |・・・| check に登録されていない item_id を表示したいと考えているのですが データの取得方法がわかりません。 例えば hid=1 の場合、item_id=4 と item_id=5 を取得したいです。 下記クエリの場合、hid に関係なく取得できてしまいます。 select i.* from items i left join check c using(item_id) where i.type='11' and c.item_id is NULL order by i.item_id ASC どうやってクエリを書いたらよろしいでしょうか。 ご教示お願いいたします。 <環境> MySQL:4.1.20

    • ベストアンサー
    • PHP
  • クエリが数秒かかる

    こんにちは、データベース初心者です。 ―――― id | tag ―――― 1 | 1002 1 | 1004 1 | 4005 2 | 3001 というような、IDに複数の検索用タグが付いているテーブルに対して、 select TB2.id from tb as TB1 inner join tb as TB2 on TB2.id=TB1.id where TB1.tag=1002 and TB2.tag=1004 limit X,Y; というような、任意の数(例は2個)の指定したtagを全て含むIDを検索するクエリがあります。 (指定が3個の場合は単純にinner join を増やしています) で、指定のtagが1つの場合は一瞬で返されるのですが、 複数指定の場合に何秒もかかるときがありまして、 一瞬で返させるには一体どこを直せばよいのかがわからないのです。 クエリを変えるのか、テーブル構成を変えるのか、マシンを変えなきゃ無理なのか、 こういった場合のセオリーなど、ご指導願いたいのです。 2つ目の質問として、 order by が無い場合というのは、データに大きな変更が無い期間中は、 同じクエリであれば同じ順序で返ってくると考えて良いのでしょうか? というのも、上記クエリにorder byを付けたかったのですが、 ソート項目が多数あり断念しまして、ただページング機能は付けたく思いまして。 環境は、ローカルで、winXP、MySQL 5.1、PHP経由で、ブラウザから操作・表示しています。 id数が約1000万、tagは500種ほどあり、1idに対して1~30個ほどで平均8個くらい付いており、 テーブルのレコード数は約8000万となっています。 素人質問で恐縮ですがよろしくお願いします。

  • 更新クエリで合計金額を入れたい

    アクセスのテーブル1を作成しました。 ID    日付    金額    合計金額 1     6/1     ¥100 2     6/1     ¥200 3     6/2     ¥150 4     6/2     ¥300 (合計金額はカラ) そして、日別の合計を出すクエリ1を作成しました。 SELECT [テーブル1].日付, Sum([テーブル1].金額) AS 金額の合計 FROM テーブル1 GROUP BY [テーブル1].日付; 元のテーブルの合計金額の列に、クエリで表示した金額の合計を更新クエリで入れようとすると、 「 更新可能なクエリであることが必要です。」となります。 更新クエリのSQL文は UPDATE クエリ1 INNER JOIN テーブル1 ON [クエリ1].日付 = [テーブル1].日付 SET [テーブル1].合計金額 = [クエリ1]![金額の合計]; です。 ヘルプの内容の 一対多リレーションシップの '一' 側のフィールドを更新するクエリを実行しようとしました。 読み取り専用で開いているデータベースのクエリで、古い OpenQueryDef メソッドで使用しています。 には該当してないのですが(リレーションシップを組んでないし、四方チリ専用で開いてないし) どうすれば元のテーブルに合計金額を入れられるのでしょうか? 結果的に ID     日付     金額     合計金額 1     6/1     ¥100     300 2     6/1     ¥200     300 3     6/2     ¥150     450 4     6/2     ¥300     450 にしたいです。

  • MySQLのクエリ結果を繰り返し表示

    MySQLとPHPで困っています。 MySQLでクエリした結果をテーブルに繰り返し表示したいと思っています。 今まではただ横一列に並べるもしくは、縦一列に並べるしかやったことがありませんでした。 下記のような感じ while($row=mysql_fetch_array($rs)){ $a = $row["id"]; echo $id<br>; } しかし今回は、横4列に並べ、5以上ある場合は数に応じて改行を行いたいのです。 (横4列は例であり、何列でも改行<tr>が伴うようなものなら構いません) □■△▲ ▽▼×○ ◎● のように。 forを使いながらいろいろと試してみましたが、何度やってもうまくいきません。 MySQLからクエリされた行総数($sum)として、変数($a)を使い、 $a<$sum $a = 0; 処理($a%4 == 3)余りが3の場合改行などなど $a++; いろいろと試しているうちに無限ループ突入など困り果ててしまいました。 どなたか、ご教示くださいますようお願いいたします。

  • 更新可能なクエリであることが必要です ACCESS

    更新可能なクエリであることが必要です Access2010で更新クエリをかけたいと思っています。やりたいことは以下になります。 クエリデザインで行おうとしています。 追加動物テーブル(重複したIDもあります。) ・ID ・数 追加動物クエリ(追加動物テーブルで数の合計をしています。重複IDがある為) ・sum(数) group by ID トータル動物テーブル(このテーブルに追加動物クエリで得た数を足し込みたいです) ・ID ・数 そこで、クエリデザインで更新クエリを行おうと思いました。 SQLは、 UPDATE トータル動物テーブル INNER JOIN 追加動物クエリ ON トータル動物テーブル.ID = 追加動物クエリ.ID SET トータル動物テーブル.数 = [追加動物クエリ]![数]; としたら、「更新可能なクエリであることが必要です」と表示されました。 目的としている、クエリで取得した数をテーブルの数に追加したいです。 例えば、トータル動物テーブルの001 猫の数が10だとします。追加動物クエリで得た猫の数が20だとします。 更新クエリが実行された時、トータル動物テーブルの猫の数が30になっていてもらいたいです。 ずっと悩んでいるのですが良いアイディアがでません。おわかりでありましたらお教え下さいませ。 宜しくお願いします。

  • Accessのクエリ内にある!マーク

    Accessのクエリ内にある!マークはどういう意味ですか? <例> SELECT table1.item1 ,([table1]![item2] + [table1]![item3]) AS name1 FROM table1

  • ACCESSクエリーについて(条件抽出等3差分)

    こちらのクエリーを活用して経過日数を算出しているのですが、 http://okwave.jp/qa/q8769213.html (SQL構文) SELECT テーブル.ID, Max(テーブル.利用日) AS 直近利用日, Max(テーブル.利用回数) AS 利用回数, Sum(テーブル.利用金額) AS 利用金額合計, Min(DateDiff("d",[利用日],DateValue([yyyymmdd]))) AS 経過日数 FROM テーブル GROUP BY テーブル.ID; パラメータのyyyymmddには「2013/12/10」のように、区切り記号付きの日付を入力。 エクセル上で同じ日付-日付の経過日数でみると、エクセルの方が1多いのですが、これはエクセルが誤りでしょうか。 例 クエリー: 2014/09/27でパラメーターを指定  2014/05/13 が直近日付 = 137 例 エクセル: 2014/09/27とセルに入力 そこから右記のセルを引く 2014/05/13 が直近日付 = 136

  • ACCESSのクエリで実行結果が上手く返らない

    商品在庫とそれぞれの賞味期限についてAccessで管理しようと思っているのですが、多々上手くいかないところがあり困っています。 今回質問させて頂きたいのはクエリに関してです。 以下のようにテーブル、リレーションシップ、クエリを作成していますが、実行しても結果が一件も返ってきません。 データはtblItem_Infoに約1000件、tblItem_Listに約1700件入っています。tblTransactionsと tblReceive とtblIssueには動作テストのための数件のみです。 リレーションを組むところから知識不足でお恥ずかしいのですが、原因また解決方法を教えていただけないでしょうか? アスタリスク付きのフィールドが主キーです。 テーブル:tblItem_Info フィールド:*Item_ID , Description , Shelf_Life テーブル:tblItem_List フィールド:*Transaction_ID , Item_ID, Inventory_Qty, Production_Date テーブル:tblTransactions フィールド:*ID , Transaction_ID , Receive_ID , Issue_ID , Receive_Qty , Issue_Qty テーブル:tblReceive フィールド:*Receive_ID , Receive_Date テーブル:tblIssue フィールド:*Issue_ID , Issue_Date リレーションは全て参照整合性にチェックで以下のようになっています。 tblItem_InfoのItem_ID - tblItem_ListのItem_ID tblItem_ListのTransaction_ID - tblTransactionsのTransaction_ID tblReceiveのReceive_ID - tblTransactionsのReceive_ID tblIssueのIssue_ID - tblTransactionsのIssue_ID クエリはデザインビューで作成したものをSQLに直すと長いですが以下のようになりました。 SELECT tblItem_List.Item_ID, tblItem_Info.Description, Sum(Nz([tblItem_List.Inventory_Qty],0)+Nz([tblTransactions.Receive_Qty],0)-Nz([tblTransactions.Issue_Qty],0)) AS On_Hand, Sum(tblTransactions.Receive_Qty) AS SumOfReceive_Qty, Sum(tblTransactions.Issue_Qty) AS SumOfIssue_Qty, tblItem_List.Production_Date, tblItem_Info.Shelf_Life, DateValue([tblItem_List.Production_Date]+[tblItem_Info.Shelf_Life]) AS Expiration_Date FROM tblReceive INNER JOIN (tblItem_Info INNER JOIN (tblIssue INNER JOIN (tblItem_List INNER JOIN tblTransactions ON tblItem_List.Transaction_ID = tblTransactions.Transaction_ID) ON tblIssue.Issue_ID = tblTransactions.Issue_ID) ON tblItem_Info.Item_ID = tblItem_List.Item_ID) ON tblReceive.Receive_ID = tblTransactions.Receive_ID GROUP BY tblItem_List.Item_ID, tblItem_Info.Description, tblItem_List.Production_Date, tblItem_Info.Shelf_Life, DateValue([tblItem_List.Production_Date]+[tblItem_Info.Shelf_Life]); また、On_Hand/在庫を求める式のところですが、この書き方でいいのか結果が返ってこないので分かりませんでした。 On_Hand:Nz([tblItem_List.Inventory_Qty],0)+Nz([tblTransactions.Receive_Qty],0)-Nz([tblTransactions.Issue_Qty],0)) 集計:合計 どうぞ宜しくお願いします。

  • グループ化したテーブルと他のテーブルの結合について

    お世話になります。PHP+MySQLでシステムを作っています。 商品のカテゴリーのテーブル・・・hametome_category(主キー:category_id ) 商品のテーブル・・・hametome_item(主キー:item_id ) 注文のテーブル・・・hametome_order(主キー:order_id ) 上記の3つのテーブルがあります。各テーブルにはそれぞれ、下記のようなデータを格納していて()内のカラムが含まれています。 hametome_category・・・カテゴリー名(category_id) hametome_item・・・商品名、単価など(category_id、item_id) hametome_order・・・注文内容等(category_id、item_id) この3つのテーブルを使い、カテゴリーごとの商品の一覧表を作り、一覧表の中に商品ごとの注文数量の累計を表示させたいと思っています。 【作りたい表のイメージ図】     単価 在庫数 注文数累計 商品A  100 1500 11000 商品B  120 1000 13000 商品C  130 1700 18000  ・  ・  ・ 表がずれていたらスイマセン^^; SELECT文を使ってデータを抽出するのですが、この際、 $sql="select * from hametome_category c,hametome_item i where i.category_id = $id and c.category_id = i.category_id ORDER BY item_id"; このようにすると任意のカテゴリーに属する商品の一覧表を出力する事は出来るのですが($idは前ページからPOSTされてきます。)、これに注文内容のデータ抽出を組み合わせようとするとうまくいきません。 この表に注文内容(hametome_orderに登録されているデータ)をitem_idでグループ化し合計したものを表示させたいです。 $sql="select *,SUM(order_amount) AS goukei from hametome_order GROUP BY item_id"; とすれば、注文数の累計をitem_idで合計しグループ化する事は出来るのですが(『order_amount』はhametome_orderテーブルに登録されている注文数です。)、この内容を最初のSELECT文にうまく組み込む事が出来ません。 どのようにすれば思うような結果を得られるでしょうか?ご教授のほどよろしくお願い申し上げます。

    • ベストアンサー
    • MySQL
  • SpringでのQuery文について

    SpringFrameworkとOracleSQLを利用しています。 Itemテーブル(商品ID,名前、在庫、画像)とOrderItemテーブル(商品ID、注文数)を商品IDで内部結合し、注文数が多い順、同じ注文数があれば商品IDの小さい順に全件表示をしたいです。その際、重複を省きたくてDISTINCTを使用していますが、SQLエラーがでてしまいます。記述してエラー(SELECT式が無効です)になった文が下記です。 @Query("SELECT DISTINCT i.name from OrderItem o INNER JOIN o.item i ORDER BY o.quantity ASC,i.id DESC") ご回答いただければ幸いです。 ※OKWAVEより補足:「Webシステム開発」についての質問です。