【问题标题】:MySQL Slow on join and order byMySQL 加入和排序缓慢
【发布时间】:2013-04-04 04:31:32
【问题描述】:

我有一个慢速查询,它连接 4 个表并按顺序排列。这将需要 +30 秒。

我有 GuruList.GuruName、GuruList.id、GuruName、Stocks.TickerName、Stocks.exchange、triple_insider.symbol、triple_insider.exchange、triple_insider.date 的索引

这是查询:

SELECT DISTINCT stock_list.symbol as t, 
                stock_list.exchange,
                REPLACE(stock_list.company, '    ', ' ') as c,
                REPLACE(triple_insider.position, '    ', ' ') as p,
                triple_insider.date as d,
                triple_insider.name as n,
                triple_insider.type as y,
                triple_insider.trans_share as r,
                triple_insider.cost as cs,
                triple_insider.price as z,
                stock_list.price as x,
                ROUND(100*(stock_list.price-triple_insider.price)/triple_insider.price, 1) as h
    FROM  triple_insider 
        LEFT JOIN stock_list 
            ON triple_insider.symbol=stock_list.symbol 
                AND triple_insider.exchange=stock_list.exchange  
        LEFT JOIN Stocks 
            ON triple_insider.symbol=Stocks.TickerName 
                AND triple_insider.exchange=Stocks.exchange  
        LEFT JOIN GuruList 
            ON Stocks.GuruName=GuruList.GuruName    
    WHERE stock_list.price > 0  
        AND stock_list.mktcap >= 100 
        AND stock_list.rank_balancesheet/10 >= 5 
        AND stock_list.volume != 0 
        AND stock_list.volume >= 200000 
        AND stock_list.price >= 2 
        AND stock_list.price <= 10 
        AND stock_list.shares != 0 
        AND stock_list.shares <= 500 
        AND stock_list.p_pct_change != 0 
        AND stock_list.p_pct_change >= 2 
        AND stock_list.cash2debt >0 
        AND stock_list.cash2debt >= 0.1 
        AND stock_list.equity2asset >0 
        AND stock_list.equity2asset >= 0.1 
        AND stock_list.fscore != 0 
        AND stock_list.fscore >= 1 
        AND stock_list.zscore != 0 
        AND stock_list.zscore >= 0 
        AND stock_list.medpsvalue > 0 
        AND stock_list.p2medpsvalue <= 0.7 
        AND stock_list.p2iv_dcf_share <= 0.5 
        AND  GuruList.id IN( 0,155 ,88 ,54 ,11 ,47 ,112 ,84 ,3 ,20 ,22 ,114 ,67 ,40 ,102 ,164 ,50 ,64 ,108 ,163)  
        AND stock_list.exchange IN ('NAS','NYSE','OTCPK','','OTCBB','AMEX')   
    ORDER BY triple_insider.date DESC
    LIMIT 5001

这是解释:

-------------------------------------------+
| id | select_type | table          | type   | possible_keys                                                                      | key      | key_len | ref                                                                       | rows | Extra                                        |
+----+-------------+----------------+--------+------------------------------------------------------------------------------------+----------+---------+---------------------------------------------------------------------------+------+----------------------------------------------+
|  1 | SIMPLE      | GuruList       | range  | PRIMARY,GuruList_GuruName,GuruList_id,GuruName                                     | PRIMARY  | 4       | NULL                                                                      |   20 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | Stocks         | ref    | GuruName,TickerName,exchange,exchange_2                                            | GuruName | 43      | g_main.GuruList.GuruName                                                  | 1490 | Using where                                  |
|  1 | SIMPLE      | triple_insider | ref    | triple_insider_symbol_index,exchange                                               | exchange | 22      | g_main.Stocks.exchange,g_main.Stocks.TickerName                           |   56 | Using where                                  |
|  1 | SIMPLE      | stock_list     | eq_ref | PRIMARY,stock_list_mktcap,stock_list_price,stockfscore,stockfzcore,symbol,exchange | PRIMARY  | 22      | g_main.triple_insider.symbol,g_main.triple_insider.exchange               |    1 | Using where                                  |
+----+-------------+----------------+--------+------------------------------------------------------------------------------------+----------+---------+---------------------------------------------------------------------------+------+----------------------------------------------+
4 rows in set (0.00 sec)

【问题讨论】:

  • 对你来说“慢”有多长时间?
  • 30 + 秒完成。
  • 第一条评论:您不能在 WHERE 子句中测试左连接表(在您的情况下为 stock_listGuruList)中的列。如果这样做,则强制 LEFT JOIN 表现得好像它是 INNER JOIN。相反,这些测试应该成为 JOIN 条件的一部分。
  • 为什么这里有DISTINCT

标签: mysql performance join sql-order-by


【解决方案1】:

triple_insider.date 上创建索引。

您可能还想删除LEFT JOIN 或将除triple_insider 之外的所有内容的条件移至适当的ON 子句。

另外,DISTINCT 本身虽然是一个合法的结构,但似乎是解决您未在帖子中描述的问题的错误方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 2012-03-12
    • 2021-10-01
    • 2017-10-26
    • 2017-08-28
    • 2010-11-24
    相关资源
    最近更新 更多