0

私のアプリケーションは Facebook に似ており、ユーザー レコードを取得するクエリを最適化しようとしています。ユーザー レコードは、彼が src ou dst であることです。は直接、リストは にありsrcます。usermuralentrydstusermuralentry_user

そのため、エントリには 1 つsrcまたは複数の を含めることができますdst

私はそれらのテーブルを持っています:

mysql> desc usermuralentry ;
+-----------------+------------------+------+-----+---------+----------------+
| Field           | Type             | Null | Key | Default | Extra          |
+-----------------+------------------+------+-----+---------+----------------+
| id              | int(11)          | NO   | PRI | NULL    | auto_increment |
| user_src_id     | int(11)          | NO   | MUL | NULL    |                |
| private         | tinyint(1)       | NO   |     | NULL    |                |
| content         | longtext         | NO   |     | NULL    |                |
| date            | datetime         | NO   |     | NULL    |                |
| last_update     | datetime         | NO   |     | NULL    |                |
+-----------------+------------------+------+-----+---------+----------------+
10 rows in set (0.10 sec)


mysql> desc usermuralentry_user ;
+-------------------+---------+------+-----+---------+----------------+
| Field             | Type    | Null | Key | Default | Extra          |
+-------------------+---------+------+-----+---------+----------------+
| id                | int(11) | NO   | PRI | NULL    | auto_increment |
| usermuralentry_id | int(11) | NO   | MUL | NULL    |                |
| userinfo_id       | int(11) | NO   | MUL | NULL    |                |
+-------------------+---------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

次のクエリは、2 人のユーザーから情報を取得します。

mysql> explain

SELECT *
FROM usermuralentry AS a
   , usermuralentry_user AS b
WHERE a.user_src_id IN ( 1, 2 )
   OR
   (
      a.id = b.usermuralentry_id
         AND b.userinfo_id IN ( 1, 2 )
   );
+----+-------------+-------+------+-------------------------------------------------------------------------------------------+------+---------+------+---------+------------------------------------------------+
| id | select_type | table | type | possible_keys                                                                             | key  | key_len | ref  | rows    | Extra                                          |
+----+-------------+-------+------+-------------------------------------------------------------------------------------------+------+---------+------+---------+------------------------------------------------+
|  1 | SIMPLE      | b     | ALL  | usermuralentry_id,usermuralentry_user_bcd7114e,usermuralentry_user_6b192ca7 | NULL | NULL    | NULL |  147188 |                                                |
|  1 | SIMPLE      | a     | ALL  | PRIMARY                                                                                   | NULL | NULL    | NULL | 1371289 | Range checked for each record (index map: 0x1) |
+----+-------------+-------+------+-------------------------------------------------------------------------------------------+------+---------+------+---------+------------------------------------------------+
2 rows in set (0.00 sec)

しかし、それには多くの時間がかかります...

最適化のヒントは?アプリケーションでテーブル スキーマを改善できますか?

4

2 に答える 2

1

結合が適切に形成されていないと思います。UNIONを使用するには、クエリを変更する必要があります。where句のOR条件も、パフォーマンスを低下させます。

SELECT *
FROM usermuralentry AS a
 JOIN usermuralentry_user AS b ON a.id = b.usermuralentry_id /* use explicit JOIN! */
WHERE a.user_src_id IN (1 , 2)
 UNION
SELECT *
FROM usermuralentry AS a
 JOIN usermuralentry_user AS b ON a.id = b.usermuralentry_id 
WHERE b.usermuralentry_id IN ( 1, 2 )   

インデックスも必要です。ALTERTABLEusermuralentry_userADD INDEX(usermuralentry_id)

于 2012-07-02T05:29:26.237 に答える
1

このクエリを使用

SELECT *
FROM usermuralentry AS a
left join usermuralentry_user AS b
on b.usermuralentry_id = a.id
WHERE a.user_src_id IN(1, 2)
OR (a.id = b.usermuralentry_id
AND b.userinfo_id IN(1, 2));

そして、ここにいくつかのヒントがあり
ます。 from 句で 2 つのテーブルを使用しています。これは、cartision 製品であり、望ましくない結果と同様に多くの時間がかかります。この状況では常に結合を使用してください。

于 2012-07-02T05:34:42.953 に答える