0

アプリの全文検索に Sphinx を使用しています。を使用しviewてテーブルからデータをフィルター処理し、productsSphinx がこのビューにインデックスを付けます。現在、製品テーブルの下に関連するタグを含むハードコードされたフィールドがありますが、タグが変更される可能性があり、ハードコードされたフィールドを毎回操作する必要があるため、あまり良くありません。

したがって、GROUP_CONCAT を使用してビューを作成し、関連するすべてのタグを次のような構文でリストできると考えていました。

SELECT p.id AS id, GROUP_CONCAT(t.tag SEPARATOR '|') AS tags,
UNIX_TIMESTAMP(p.created) AS created
FROM products p
INNER JOIN products_tags pt ON pt.product_id = p.id
INNER JOIN tags t ON t.id = pt.tag_id
AND p.deleted = 0
AND (p.images IS NOT NULL OR p.images <> '')
AND p.status LIKE 'listed'
GROUP BY p.id;

このクエリの問題は、実行に時間がかかることです。本当に遅いです。1 つのレコードのみを取得するには、最大 5 秒かかります。これはEXPLAIN出力です:

1, SIMPLE, pt, ALL, , , , , 165029, Using temporary; Using filesort
1, SIMPLE, p, eq_ref, PRIMARY, PRIMARY, 4, trych_default.pt.product_id, 1, Using where
1, SIMPLE, t, eq_ref, PRIMARY, PRIMARY, 4, trych_default.pt.tag_id, 1, 

クエリを改善する方法や、私の問題に対するより良い解決策があるのではないかと思います。ありがとう!

4

1 に答える 1

3

おそらくインデックスがありません。次のスキーマでは、この同じクエリがすべてのテーブルのインデックスにヒットします。

CREATE TABLE `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `deleted` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `status` varchar(255) NOT NULL DEFAULT 'listed',
  `images` varchar(255) DEFAULT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `tags` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `tag` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `products_tags` (
  `product_id` int(11) NOT NULL,
  `tag_id` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`product_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

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

EXPLAIN SELECT p.id AS id, GROUP_CONCAT(t.tag SEPARATOR '|') AS tags,
UNIX_TIMESTAMP(p.created) AS created
FROM products p
INNER JOIN products_tags pt ON pt.product_id = p.id
INNER JOIN tags t ON t.id = pt.tag_id
WHERE p.deleted = 0
AND (p.images IS NOT NULL OR p.images <> '')
AND p.status LIKE 'listed'
GROUP BY p.id;

+----+-------------+-------+--------+---------------+---------+---------+----------------+------+-------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref            | rows | Extra       |
+----+-------------+-------+--------+---------------+---------+---------+----------------+------+-------------+
|  1 | SIMPLE      | p     | index  | PRIMARY       | PRIMARY | 4       | NULL           |    1 | Using where |
|  1 | SIMPLE      | pt    | ref    | PRIMARY       | PRIMARY | 4       | test.p.id      |    1 | Using index |
|  1 | SIMPLE      | t     | eq_ref | PRIMARY       | PRIMARY | 4       | test.pt.tag_id |    1 |             |
+----+-------------+-------+--------+---------------+---------+---------+----------------+------+-------------+
3 rows in set (0.00 sec)
于 2011-05-13T17:11:02.690 に答える