1

現在 2.5 秒で実行されている MySQL クエリがあり、最大 2 秒に短縮したいと考えています。

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

SELECT SQL_CALC_FOUND_ROWS Distinct(c.id) 
FROM   `content` c 
       INNER JOIN `actions` AS action 
               ON c.parent_id = action.primary_id 
WHERE  1 = 1 
       AND c.site_id IN ( 1, 2 ) 
       AND c.type IN ( 'topic' ) 
       AND c.status = 'visible' 
       AND ( c.lock = 0 
              OR c.site_id = 1 ) 
       AND ( c.level IN ( 0 ) 
              OR ( c.level IN ( 10 ) 
                   AND action.user_id = 123 
                   AND action.type IN ( 'group_follow' ) ) ) 
ORDER  BY c.date_updated DESC 
LIMIT  20 

現在の統計は次のとおりです。

  • テーブル コンテンツには 55,000 行あります
  • テーブル アクションには 87,000 行あります

コンテンツについては、次のインデックスがあります。

  • 親 ID (親 ID)
  • ユーザー ID (ユーザー ID)
  • type_status_date (タイプ、ステータス、日付)
  • type_status_updateddate (タイプ、ステータス、date_updated)
  • サイト_id (サイト_id)
  • type_status_level (タイプ、ステータス、レベル)
  • type_parentid_level (タイプ、親 ID、レベル)

アクションについては、次のインデックスがあります。

  • primary_id (プライマリ ID)
  • サイト_id (サイト_id)
  • タイプ(タイプ)

どんな助けや提案も大歓迎です。

皆さんありがとう!

4

2 に答える 2

1

「ORDER BY c.date_updated DESC LIMIT 20」を実行しているので、おそらく c.date_updated にインデックスが必要です。そうすれば、mysql は最初にそのテーブルを逆のdate_updated順序でスキャンし、20 行を取得するとすぐに停止できます。

EXPLAINオプティマイザーがその順序を選択するかどうかを確認するために、変更の前後にクエリを確認するために必ず使用する必要があります。date_updatedオプティマイザーがインデックスを自然に選択しない場合、強制的にインデックスを使用する方法があります。

于 2012-12-22T00:35:02.800 に答える
0

where句では、順序が必要です。firsts は、インデックスを持つ列である必要があります。

たとえば、インデックス type_status_updateddate (タイプ、ステータス、date_updated) の場合

書くと

where status = 'blabla' and type = '1'

ナットを使用しないインデックス

where type='1' and status='blala'

インデックスを使用します。

列がインデックスに残っている場合、mysqlはインデックスを使用します(複数列インデックス内)。たとえば、インデックス type_status_updateddate (タイプ、ステータス、date_updated) の場合

where status = 'blablabla' index not using と書くと

この事実は、複数列のインデックスを使用することはクールではありません

c.type IN ( 'topic' )

で交換することができます

c.type = 'topic' 

私の英語でごめんなさい。

于 2012-12-23T16:32:15.603 に答える