2012-01-17 16 views
1

私はすべての12カテゴリの25の項目をリストするスクリプトを書いています。データベース構造は次のようになります。最新のレコードを取得するSQL LIMIT

tbl_items 
--------------------------------------------- 
item_id | item_name | item_value | timestamp 
--------------------------------------------- 

tbl_categories 
----------------------------- 
cat_id | item_id | timestamp 
----------------------------- 

tbl_itemsの表には約60万行あります。 6012まで6000からcat_idためのループ内で同じクエリを使用して

SELECT e.item_id, e.item_value 
    FROM tbl_items AS e 
    JOIN tbl_categories AS cat WHERE e.item_id = cat.item_id AND cat.cat_id = 6001 
    LIMIT 25 

しかし、私はすべてのカテゴリの最新のレコードをしたい:私はこのSQLクエリを使用しています。私はのようなものを使用している場合:

SELECT e.item_id, e.item_value 
    FROM tbl_items AS e 
    JOIN tbl_categories AS cat WHERE e.item_id = cat.item_id AND cat.cat_id = 6001 
    ORDER BY e.timestamp 
    LIMIT 25 

..theクエリは受け入れられない約10分間のコンピューティング行きます。 LIMITを各カテゴリの最新の25レコードに与えるのにもっとうまく使えますか?

ORDER BYなしで誰でも達成できますか?どんなアイデアや助けも高く評価されます。

EDIT

tbl_items 

+---------------------+--------------+------+-----+---------+-------+ 
| Field    | Type   | Null | Key | Default | Extra | 
+---------------------+--------------+------+-----+---------+-------+ 
| item_id    | int(11)  | NO | PRI | 0  |  | 
| item_name   | longtext  | YES |  | NULL |  | 
| item_value   | longtext  | YES |  | NULL |  | 
| timestamp   | datetime  | YES |  | NULL |  | 
+---------------------+--------------+------+-----+---------+-------+ 

tbl_categories 

+----------------+------------+------+-----+---------+-------+ 
| Field   | Type  | Null | Key | Default | Extra | 
+----------------+------------+------+-----+---------+-------+ 
| cat_id   | int(11) | NO | PRI | 0  |  | 
| item_id  | int(11) | NO | PRI | 0  |  | 
| timestamp  | datetime | YES |  | NULL |  | 
+----------------+------------+------+-----+---------+-------+ 
+0

テーブル作成ステートメントを表示してください。インデックスは正しいですか? –

+0

私は質問を編集しました。 – Astha

+1

@Astha - あなたが持っているインデックスと、新しいインデックスをリクエスト/作成できるかどうか確認できますか? – MatBailie

答えて

1

まず第一に:

Nのようだ:itemscategories間のMの関係:itemは、いくつかのcategoriesであってもよいです。 categoriesにはitem_idの外部キーがあるので、これを言う。

N:Mの関係でない場合は、デザインを変更することを検討する必要があります。カテゴリが複数の項目を持つ1:Nの関係の場合、itemcategory_idの外部キーを保持する必要があります。 Nでの作業

:M:

私は内部結合クロスinsteat参加するために、クエリを書き換えています

SELECT e.item_id, e.item_value 
    FROM 
    tbl_items AS e 
    JOIN 
    tbl_categories AS cat 
     on e.item_id = cat.item_id 
    WHERE 
    cat.cat_id = 6001 
    ORDER BY 
    e.timestamp 
    LIMIT 25 

パフォーマンスに必要なインデックスを最適化するには、以下のとおりです。

create index idx_1 on tbl_categories(cat_id, item_id) 

主キーも索引付けされるため、項目の索引は必須ではありません。 タイムスタンプを含むインデックスは、mutchとして役立ちません。

:あなたは、単一のクエリによってカテゴリの上にループを変更することができます性能もを高めるために

create index idx_2 on tbl_items(item_id, timestamp) 

:確かにはitem_idtimestampとアイテムのインデックステーブルへのアクセスを避けるために、インデックスから値を取るとしてみてください

select T.cat_id, T.item_id, T.item_value from 
    (SELECT cat.cat_id, e.item_id, e.item_value 
    FROM 
    tbl_items AS e 
    JOIN 
    tbl_categories AS cat 
     on e.item_id = cat.item_id 
    ORDER BY 
    e.timestamp 
    LIMIT 25 
) T 
    WHERE 
    T.cat_id between 6001 and 6012 
    ORDER BY 
    T.cat_id, T.item_id 

このquerysを試してみて、必要に応じてコメントを付けてください。私は結果がlongtext列が含まれているため、クエリが非常に遅くなる主な理由は、あることを伝えることができ、他のすべての要因を別にして

+0

返信いただきありがとうございます。 dbの構造を変更することはできません。はい、それは1:N関係テーブルです。 1つのitem_idは1つのカテゴリのみになります。私はこのクエリを試みたが、同じ時間を取っている。私はカテゴリIDのためのループを使用しています。私はcaluseの間でこのような単一のクエリを使用することはできません。あなたが私のポイントを得たことを願って – Astha

+1

データベースがない場合は、簡単な解決策ではありません。この関連する質問を見てみましょう:[クロステーブルのインデックス作成は可能ですか?](http://stackoverflow.com/questions/8509026/is-cross-table-indexing-possible) – danihp

1

あなたはインデックスを追加することはできますか? timestampと他の適切な列にインデックスを追加すると、ORDER BYに10分かかることはありません。

+0

返信ありがとうございますが、どのようなインデックスですか?説明してください? – Astha

+0

インデックスは電話帳のようなものです。電話帳に注文がない場合、誰かの電話番号を調べるのに数時間かかるでしょう。タイムスタンプ列のインデックスは、レコードがどこにあるかをタイムスタンプ*によってMySQLに知らせるので、電話帳のように行を検索できます。 – toon81

+0

残念ながら、私はあなたが始めるためにまともなウェブサイトを知らない。 (誰ですか?) – toon81

1

BLOBおよびTEXT MySQLのフィールドは、ほとんどがテキストまたはバイナリの完全なファイルを格納するためのものです。 InnoDBテーブルの行データとは別に格納されます。クエリーが(明示的にまたはgroup byのために)ソートを呼び出すたびに、MySQLはソートにdiskを使用することになります(どのファイルがどれくらい大きいかを事前に確かめることはできません)。

そして、それはおそらく、親指のルールです:あなたは、クエリ内の列の単一の行以上を返すために必要がある場合は、フィールドのタイプは、TEXTBLOBも代わりVARCHARVARBINARYを使用する必要がありますなることはほとんどありません。

UPD

あなたがテーブルを更新できない場合は、クエリは、ほとんど現在のインデックスと列の型を持つ速いません。しかし、とにかく、あなたの問題によく似た質問と一般的な解決策があります:How to SELECT the newest four items per category?

+0

この説明をありがとう。本当に感謝しますが、私はこのデータベースは私のものではないと言いました。私は表示するデータを取得する必要があります。 – Astha

+0

@astha、私は私の答えを更新しました。 – newtover

+0

助けてくれてありがとう! – Astha

関連する問題