0
SELECT
    n.id,
    n.title,
    n.text,
    n.date,
    IFNULL(ap.name, a.name) AS name,
    IFNULL(ap.path, a.path) AS path,
    IFNULL(ap.extension, a.extension) AS extension,
    IFNULL(ap.width, a.width) AS width,
    IFNULL(ap.height, a.height) AS height,
    IFNULL(ap.server, a.server) AS server,
    s.id AS source_id,
    s.name AS source_name
FROM news n
LEFT JOIN news_attachments na ON n.id = na.news_id AND na.cover = 1
LEFT JOIN attachments a ON na.attachments_id = a.id
LEFT JOIN attachments ap ON a.id = ap.parent AND ap.width = 136
JOIN sources s ON n.sources_id = s.id
WHERE n.moderate = 1 AND n.delete = 0
GROUP BY n.id
ORDER BY n.date DESC
LIMIT 25

このSQLクエリがあります。そして、私はそれが良いかどうかという質問がありますか?多分私はそれを改善することができますか?

この部分では

LEFT JOIN attachments a ON na.attachments_id = a.id
LEFT JOIN attachments ap ON a.id = ap.parent AND ap.width = 136

画像のプレビューをロードしてから、次を選択します。

    IFNULL(ap.name, a.name) AS name,
    IFNULL(ap.path, a.path) AS path,
    IFNULL(ap.extension, a.extension) AS extension,
    IFNULL(ap.width, a.width) AS width,
    IFNULL(ap.height, a.height) AS height,
    IFNULL(ap.server, a.server) AS server

これは、画像のプレビューがある場合はそれを使用し、それ以外の場合は元の画像を使用することを意味します

説明:

+----+-------------+-------+--------+-------------------------------------------+----------------------+---------+--------------------------+------+---------------------------------+
| id | select_type | table | type   | possible_keys                             | key                  | key_len | ref                      | rows | Extra                           |
+----+-------------+-------+--------+-------------------------------------------+----------------------+---------+--------------------------+------+---------------------------------+
|  1 | SIMPLE      | s     | ALL    | PRIMARY,id                                | NULL                 | NULL    | NULL                     |    4 | Using temporary; Using filesort |
|  1 | SIMPLE      | n     | ref    | fk_news_sources1_idx                      | fk_news_sources1_idx | 4       | base.s.id              |   93 | Using where                     |
|  1 | SIMPLE      | na    | ref    | PRIMARY,fk_news_has_attachments_news1_idx | PRIMARY              | 4       | base.n.id              |    1 |                                 |
|  1 | SIMPLE      | a     | eq_ref | PRIMARY,id                                | PRIMARY              | 4       | base.na.attachments_id |    1 |                                 |
|  1 | SIMPLE      | ap    | ALL    | NULL                                      | NULL                 | NULL    | NULL                     | 3720 |                                 |
+----+-------------+-------+--------+-------------------------------------------+----------------------+---------+--------------------------+------+---------------------------------+
4

2 に答える 2

1

添付テーブルに親のキーがあることを確認してください (または、親と幅をカバーするキーの方がよいでしょう)。これが主要な問題であると思われます。

ニュース テーブルのモデレート カラムと削除カラムでは、それらのインデックスを有効にするのに十分なほど絞り込まれないのではないかと思います。

また、ニュース レコードよりもはるかに多くのソース レコードが存在すると推測します。そのため、MySQL はソースを取得してニュースをそれに結合することを選択し、その逆ではありません。

于 2013-07-13T13:24:53.583 に答える
1

newsすべてのレコードに があると仮定して、 、 、sourcesのニュースにインデックスを (この順序で) 追加してから、次のクエリを試してください。moderatedeletedate

SELECT
    n.id,
    n.title,
    n.text,
    n.date,
    IFNULL(ap.name, a.name) AS name,
    IFNULL(ap.path, a.path) AS path,
    IFNULL(ap.extension, a.extension) AS extension,
    IFNULL(ap.width, a.width) AS width,
    IFNULL(ap.height, a.height) AS height,
    IFNULL(ap.server, a.server) AS server,
    s.id AS source_id,
    s.name AS source_name
FROM (select *
      from news
      WHERE moderate = 1 AND delete = 0
      ORDER BY date DESC
      LIMIT 25) n
LEFT JOIN news_attachments na ON n.id = na.news_id AND na.cover = 1
LEFT JOIN attachments a ON na.attachments_id = a.id
LEFT JOIN attachments ap ON a.id = ap.parent AND ap.width = 136
JOIN sources s ON n.sources_id = s.id
GROUP BY n.id
于 2013-07-13T11:28:41.017 に答える