0

次のようなクエリがあります。

select row_number() over(order by m_time desc) as row, m.m_id, m_time, m_log_id
    (case when exists(select 1 from t_approved_phonenumber where phone_number = m.c_phone_number) then 1 else 0 end) as approved, 
    (case when exists(select 1 from t_log log where log.c_id < m.m_log_id and log.phone_number = m.phone_number) then 'N' else 'Y' end) as is_first_time
from t_message m

すべてのテーブル t_approved_phonenumber、t_message、および t_log には多くのレコードがあります。すべての ID は主キーで、 phone_number 列にはインデックスがあります。クエリが非常に遅い場合があります。スピードアップする方法はありますか?

ありがとう、

4

3 に答える 3

0

おそらく、t_log最初の列phone_numberと2番目の列でインデックスを作成して、2番目の列c_idがこのインデックスを使用できるようにし、-DBMSに依存して-テーブルt_log自体にアクセスする必要さえないかもしれません。インデックスを一意であると宣言すると、オプティマイザでの使用が促進されますが、もちろんこれは、それが本当に一意である場合にのみ実行できます。

そしてもちろん、m_time にインデックスがない場合は作成します。これはおそらくrow_number().

于 2013-08-21T18:22:31.777 に答える
0

通常はパフォーマンスが向上するため、相関サブクエリを単純な「左結合」サブクエリに置き換えるようにしてください。各行に対して実行される相関サブクエリとは対照的に、通常のサブクエリは一度だけ実行されます。また、より柔軟です。必要に応じて、サブクエリにデータを追加できます。クエリは次のようになります (エラーが発生する可能性があります。現在、Management Studio はありません)。

select 
    row_number() over(order by m_time desc) as row
    ,m.m_id
    ,m_time
    ,m_log_id
    ,coalesce(approved, 0) as approved
    ,coalesce(is_first_time, 'Y') as is_first_time
from 
    t_message m
    left join (select phone_number, 1 as [approved] from t_approved_phonenumber group by phone_number) as a
    on a.phone_number = m.c_phone_number
    left join (select phone_number, min(c_id) as c_id, 'N' as is_first_time from t_log group by phone_number) log
    on log.c_id < m.m_log_id and log.phone_number = m.phone_number
于 2013-08-21T19:23:54.167 に答える
0

私の経験joinsでは、述語で選択するよりもはるかに優れています。このクエリを試してください。

各 t_message に対して、それぞれに少なくとも 1 つの呼び出しがあると想定しているためPhone_Number、2 番目の左結合の代わりにt_message使用しています。INNER JOINJOIN

select row_number() over(order by m_time desc) as row, 
    m.m_id, 
    m_time, 
    m_log_id,
    (case WHEN approved.phone_number IS NULL then 0 else 1 end) as approved, 
    (case when First_c_id < m.m_log_id then 'N' else 'Y' end) as is_first_time
from t_message  m
LEFT JOIN t_approved_phonenumber approved ON m.c_phone_number = approved.phone_number 
INNER JOIN (SELECT phone_number, MIN(c_id)  AS First_c_id 
           FROM t_log 
           GROUP BY phone_number) FirstLog ON FirstLog.PhoneNumber = m.phone_number

とにかく、@FrankPl によって提案されたインデックスは、パフォーマンスを大幅に向上させるのに役立ちます。

于 2013-08-21T19:28:06.887 に答える