簡體   English   中英

如何優化慢速MySQL查詢

[英]How to optimize slow MySQL query

我有以下MySQL查詢,它需要很長時間才能執行:

SELECT `market`.`name` AS `Markets`, count(*) * `clicks`.`cost` AS `Rev`
FROM `clicks`
INNER JOIN markets ON `clicks`.`market_id`= `markets`.`id`
WHERE clicks.created_date = `date1`
GROUP BY `markets`.`id`
ORDER BY `Rev` DESC

最初它非常慢,但后來我刪除了冗余日期功能。 仍然需要很長時間才能執行。 有什么解決方案嗎?

查詢說明:我從一個表和行數中選擇市場名稱乘以另一個表的成本。 市場ID在第一個表“點擊”中定義,我從“市場”表中獲取市場名稱。 我進一步按照他們的ID對市場進行分組,然后通過Rev降序排序

您的查詢是功能濫用MySQL 部分組 您按市場進行分組,但有一個clicks.cost列的clicks.cost ,它不包含在聚合中。 無論查詢速度有多快,您都會得到錯誤的結果。

您可以按如下方式修改查詢:

SELECT market.name AS Markets, subqry.Rev FROM (
    SELECT market_id, SUM(cost) AS Rev
    FROM clicks
    WHERE created_date = 'some date'
    GROUP BY market_id
) AS subqry
INNER JOIN markets ON subqry.market_id = markets.id
ORDER BY Rev DESC

確保結果正確后,請創建以下索引:

CREATE INDEX ix_clicks ON clicks (created_date, market_id, cost)

據推測,你打算:

SELECT m.name AS Markets, SUM(c.cost) AS `Rev`
FROM clicks c INNER JOIN
     markets m
     ON c.market_id = m.id
WHERE c.created_date = ?
GROUP BY m.name
ORDER BY Rev DESC;

這對性能沒有幫助。 但是, clicks(created_date, market_id, cost)索引clicks(created_date, market_id, cost)可能會為您提供所需的性能。

如果這不起作用,那么試試這個:

SELECT m.name AS Markets,
       (SELECT SUM(c.cost)
        FROM clicks c
        WHERE c.market_id = m.id AND c.created_date = ?
       ) AS `Rev`
FROM markets m
ORDER BY Rev DESC;

這將刪除外部GROUP BY ,這可以獲得很大的性能提升。 為此,索引應略有不同, clicks(market_id, created_date, cost)

我知道這不是問題的直接答案,如果你願意,你可以向我投票(我理解人性,對另類思想家表現出仇恨)。


但是我要編寫另外正確的方法來做這樣的邏輯系統,我們每天都有大量的數據,而且我們必須在沒有性能問題的情況下制作摘要報告。


不幸的是,這是時間序列數據。

它會增長並且會損失您的性能損失。

對於短期添加索引可能會解決您的問題。

但從長遠來看 ,許多市場將出現,點擊量將達到每天約100萬 ,“索引解決方案” 並不是一個好的解決方案。

A)如果你做索引日期字段你會慢速插入。 因為它每次都會在后台執行索引更新程序。

B)如果您對分區表進行分區,那么在一段時間之后很難管理,因為擁有數百個分區是不好的,並且某些日常業務將為當前數據結構帶來非常“不舒服”的任務,這將導致重新思考表模式。


解決方案是重新思考你的邏輯:

  1. 使用Kafka並將您的點擊數據插入其中。
  2. 將數據插入到clicks表(表不應該有索引以快速插入)。
  3. 讓工作人員從Kafka獲得點擊數據,做數學,並按天,周,月,年等市場創建摘要。通過創建表: clicks_by_marketsclicks_by_markets_yearlyclicks_by_markets_weeklyclicks_by_markets_daily

另一個解決方案(沒有Kafka):

  1. 使用表clicks_raw來放置請求數據而不進行處理。
  2. 創建將每10分鍾安排一次的腳本並處理clicks_raw表並填充表格,如: clicks_by_marketsclicks_by_markets_yearlyclicks_by_markets_weeklyclicks_by_markets_daily

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM