1

私の問題は、追加する行が多いほど、SQL クエリの結果を取得するのに時間がかかることです。膨大な数の行 (10,000 から 80,000 の間) について話しているわけではありません。最初は、クエリから結果を取得するのに数ミリ秒かかりましたが、昨日は 50 行を表示するのに最大 3 分かかりましたが、今日からは最大になります。

致命的なエラー: 247 行目の C:\wamp\apps\phpmyadmin3.5.1\libraries\dbi\mysqli.dbi.lib.php で最大実行時間が 300 秒を超えました

何が悪いのかわかりません (私は SQL 初心者です)。私はこれですでに2か月間苦労しています。私は物事をスピードアップするためにインターネット上で見つけることができるすべての解決策を試しました(ここを含む)、ホスト、phpMyAdmin、MySQL、httpd.config、iPV6などの構成ファイルを変更しました。これでうまくいきました。すべての変更をロールバックし、一意の uuidを追加して新しいデータベースを作成し、データベース内のテーブルに参加しました。

しかし、それでもカメナマケモノのように遅いです!!

PHP、MySQL、Apache ローカル サーバー (WAMPP) の問題なのか、それとも SQL レベルのデータ構造の問題なのかはわかりません (主キーも一意キーもインデックスもありません。 then の使い方がわからないので設定します)。

私が何をしているか、何をしようとしているのかについて、いくつかの背景情報をお伝えしましょう。

毎日、いくつかのAPI 呼び出しを行って、特定の検索エンジンからの商品や検索に関するさまざまな広告のランキング ポジションを取得しています。Python を使用して API オブジェクトを解析しますが、データを MySQL データベースに挿入することもできます。

各ページの結果には、検索エンジンとの関連性によって並べられた 50 個の製品広告のリストがあります。このランキング順位は毎日変わります。各ランキング順位リストは、検索エンジンで使用されるキーワード (「キー」) に応じて生成されます。各製品はそのプロパティを毎日変更できますが、常に同じ一意の ID (「ad_id」) を持ちます。たとえば、製品 ad_id = a001 は、今日は前日よりも 200 回多い訪問を示しているか、販売者が「エイリアス」を変更した可能性があります。

ランキング ポジション リスト (ランキング データベース) でuuid 文字列を生成し、そこからその uuid を他のデータベースにアタッチします。

これらは私のテーブルです(下のリンクを参照)。わかりやすくするために単純化しすぎました。表には最初の 3 行のみが表示されます。RANKINGS、ITEMS、および USERS の 3 行目には異なる日付が表示されていることに注意してください(これは、毎日データベースを更新しているためです)。

http://oi49.tinypic.com/11ceidz.jpg

これは実際に私のデータ構造がどのように見えるかです (単純化しすぎた例に基づく):

ランキング

  • c_id int(11)、null 以外、AUTO_INCREMENT
  • ad_id varchar(20)、null 以外
  • ランク int(3) null 以外
  • 販売者 int(20)、null 以外
  • キー varchar(30)、null 以外
  • 日付タイムスタンプ、CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
  • uuid varchar(36)

ユーザー

  • c_id int(11)、null 以外、AUTO_INCREMENT
  • 販売者 int(20)、null 以外
  • エイリアス varchar(30)、null 以外
  • 日付タイムスタンプ、CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
  • uuid varchar(36)

アイテム

  • c_id int(11)、null 以外、AUTO_INCREMENT
  • ad_id varchar(20)、null 以外
  • タイトル varchar(30)、null 以外
  • 字幕 varchar(30), null
  • int(11) にアクセスします。null ではありません
  • 日付タイムスタンプ、CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
  • uuid varchar(36)

そして、これは私のクエリです:

SELECTrankings.key、rankings.rank、items.visits、users.seller、users.alias、rankings.ad_id、items.title、rankings.date

FROMランキング

LEFT JOIN ランキングのアイテム.uuid = items.uuid

LEFT JOIN users ON rankings.seller = users.seller

WHERE ランキング.キー = 'りんご'

GROUP BY rankings.date、rankings.rank

私が間違っていることは何ですか?ヘルプ/ヒントをいただければ幸いです。そして、事前に助けてくれてありがとう!

EDIT : GROUP BY行を削除してLIMIT 0を追加すると、50クエリの結果は数ミリ秒しかかかりませんが、大量の重複行が発生します! Limit 0 の場合、500 = わずか 4 秒です。

2番目の編集Scorpi0はそれを釘付けにしました!!! 以下の彼/彼女の答えを参照してください。

4

2 に答える 2

5

わお!

使用方法がわからないため、主キーも一意キーもインデックスセットもありません

真剣に?それから学びます!!
インデックスがない場合、クエリは 3 つのテーブルで O(n^3) で実行されます。インデックスを使用すると、O(log n) で実行されます。

とにかく走れ

CREATE INDEX idxrankginsuuid ON rankings(uuid);
CREATE INDEX idxrankingsseller ON rankings(seller);
CREATE INDEX idxrankingskey ON rankings(key);

CREATE INDEX idxitemsuuid ON items(uuid);

CREATE INDEX idxuserseller ON users(seller);

そして、パフォーマンスが向上していることに気付くでしょう。

主キーとインデックスがどのように機能するかを知らずに SQL を実行することはできません。

于 2013-04-12T16:41:14.470 に答える
0

サーバーは単純なものではないため、クエリの処理に時間がかかりすぎます。クエリとデータベースの構造を調整MySQLしてプロセスを高速化するか、それができない場合はset_time_limit(0);、スクリプトの先頭に追加して、PHP スクリプトの最大実行時間を無制限に変更します。

于 2013-04-12T16:15:25.283 に答える