1

次のクエリは、約50万行のテーブルで実行するのに20秒以上かかります。

SELECT images.id, images.user_id, images_locale.filename, extension, size, width, height, views, batch, source, status, images.created_at, images.category_id, title, short_description, long_description, alternate, slugs.name as slug, images_locale.slug_id, path_cache AS category_path, full_name, users.username
FROM images
JOIN images_locale ON images_locale.image_id = images.id JOIN slugs ON images_locale.slug_id = slugs.id JOIN categories_locale ON images.category_id = categories_locale.category_id JOIN users ON users.id = images.user_id
WHERE slugs.name = 'THE_SLUG_HERE' AND images.status = '1' AND images_locale.locale_id = 1 AND categories_locale.locale_id = 1
LIMIT 1

削除するslugs.name = 'THE_SLUG_HERE' ANDと、数ミリ秒で結果が得られます。

これは私のスラッグテーブルです:

CREATE TABLE `slugs` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(250) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
  `type` tinyint(4) NOT NULL,
  `locale_id` smallint(6) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=3611900 DEFAULT CHARSET=utf8;

私はしようとしましCREATE INDEX test_speed ON slugs(name)たが、それは物事をスピードアップしませんでした。

助けてください。

編集:

EXPLAINの結果は次のとおりです。

<code> EXPLAIN</code>の結果

4

2 に答える 2

1

可能なすべての条件をON結合の節に移動します。

SELECT ...
FROM images
JOIN images_locale ON images_locale.image_id = images.id
    AND images_locale.locale_id = 1
JOIN slugs ON images_locale.slug_id = slugs.id
    AND slugs.name = 'THE_SLUG_HERE'
JOIN categories_locale ON images.category_id = categories_locale.category_id
    AND categories_locale.locale_id = 1
JOIN users ON users.id = images.user_id
WHERE images.status = '1' 
LIMIT 1

これが機能する理由は、句がすべてのWHERE可能な結合の結果をフィルタリングするためですが、条件を句に移動すると、不要であることがわかっている行の後続のすべてのテーブルを結合することを避けます。ON

これにより、何百万もの不要な結合を回避できます。

于 2012-10-08T01:23:05.650 に答える
0

結合の順序を変更してみてください。説明の結果から、インデックスは画像テーブルを1.4kレコードにしかカットできないことがわかります。だからあなたの関節はその数から始まっています。たぶん、スラッグテーブル(名前は一意だと思います)でジョイントを開始し、名前条件付きフィルターを結合のon部分に配置することができます。

使用されるすべてのフィールドをインデックスに含めることができるように、複合キーを調査することもできます。キースキャンはファイルスキャンよりも高速です。

最後に、mysqlがどのように構成されているかを調べます。クエリに一時テーブルを使用していますか?または最悪の場合、ディスクベースの一時テーブル。

データベースの完全な範囲がわからないことをcosに伝えるのは少し難しいです。たとえば、すべてのテーブルのサイズ、キーに設定されたバッファの量、ソートバッファなど。

于 2012-10-09T01:03:20.943 に答える