0

Having an issue with with a very slow mysql query using left joins.

SELECT ip,T1.ipaddr,host,referrer,agent,page,url,thedate,DV,PV,notes
FROM visits_temp AS T1
LEFT JOIN (
    SELECT ipaddr,COUNT(DISTINCT LEFT(thedate,10)) AS DV
    FROM visits GROUP BY ipaddr
) AS T2 ON T1.ipaddr = T2.ipaddr
LEFT JOIN (
    SELECT ipaddr,notes
    FROM topvisitors
) As T3 ON T3.ipaddr = T1.ipaddr
LEFT JOIN (
    SELECT ipaddr,COUNT(ip) AS PV
    FROM visits
    GROUP BY ipaddr
) AS T4 ON T4.ipaddr = T1.ipaddr
WHERE referrer = '' AND
    thedate BETWEEN '2013-01-07 00:00:00' AND '2013-01-09 23:59:59'
GROUP BY T1.ip
ORDER BY thedate desc

The goal here is to get all the direct visitors traffic for the website than the LEFT JOINS do a find to give the total number of Days Visited (DV) and the total number of Pages Viewed (PV). The visits table has about 2.9m records currently and the ipaddr and thedate field ARE indexed. This query takes close to 90 secs to complete.

SELECT ipaddr,COUNT(DISTINCT LEFT(thedate,10)) AS DV FROM visits GROUP BY ipaddr

or

SELECT ipaddr,COUNT(ip) AS PV FROM visits GROUP BY ipaddr

The individual select statements in the LEFT JOINS when ran by themselves will complete in 0.03 seconds. Maybe LEFT JOIN isn't the right way to go in this situation I'd be open to alternatives.

4

2 に答える 2

0

where句でreferrerとthedateを使用しています。visits_temp テーブルのこれら 2 つのフィールドに複合インデックスを作成すると、パフォーマンスが向上する場合があります。

topvisitors テーブルの ipaddr フィールドにもインデックスがあることを確認してください。

于 2013-01-09T16:45:46.873 に答える
0

これら 4 つのサブクエリは、おそらく少し速度を落としています。

これはクエリと同じである必要がありますが、より高速です。

SELECT ip,T1.ipaddr,host,referrer,agent,page,url,thedate,DV,PV,notes
FROM visits_temp AS T1
LEFT JOIN (
    SELECT ipaddr, COUNT(DISTINCT LEFT(thedate,10)) AS DV, COUNT(ip) AS PV
    FROM visits
    GROUP BY ipaddr
) AS T2 ON T1.ipaddr = T2.ipaddr
LEFT JOIN topvisitors T3 ON T3.ipaddr = T1.ipaddr
WHERE referrer = '' AND
    thedate BETWEEN '2013-01-07 00:00:00' AND '2013-01-09 23:59:59'
GROUP BY T1.ip
ORDER BY thedate desc

のすべての行がとT1に一致する行を持つことが保証されている場合は、をに置き換えることができます。これにより、オプティマイザーがより多くのことを実行できるようになり、速度も向上します (例外はありますが)。T2T3LEFT JOINJOIN

これが目的の結果を返すとは想像できません。ipaddrグループ化されますが、各 に対してこれらのグループ化の (任意の) 1 つだけが返されますip。MySQL はこれを防ぎません。(使用するフィールド/テーブルに関して)要件を少し詳しく説明すると、これを修正するのはそれほど難しくありません(ただし、これはおそらく技術的には別の質問に属します)。

于 2013-01-11T10:29:43.817 に答える