mysql - INDEX 没有改善 sql 查询结果

标签 mysql

我有这个 SQL 命令:

SELECT t1.timestamp, t1.fee, t1.fee_unit, t1.profit, t1.profit_unit, t1.profit_fee_pair, price_trading.bid_price, price_trading.ask_price
FROM (
    SELECT trading_fredy.timestamp, SUM(trading_fredy_fee.fee) AS fee, trading_fredy_fee.fee_unit, trading_fredy.profit, trading_fredy.profit_unit,
        IF (trading_fredy.profit_unit = 'BTC' OR
        trading_fredy.profit_unit = 'ETH' OR
        trading_fredy.profit_unit = 'USDT', 
        CONCAT(trading_fredy_fee.fee_unit, trading_fredy.profit_unit),
        CONCAT(trading_fredy.profit_unit, trading_fredy_fee.fee_unit)) AS profit_fee_pair
    FROM trading_fredy
    LEFT JOIN trading_fredy_fee
    ON trading_fredy.order_id = trading_fredy_fee.order_id
    WHERE trading_fredy_fee.fee != 0
    AND trading_fredy.status = 'CLOSED'
    GROUP BY trading_fredy.timestamp
    ORDER BY trading_fredy.date ASC    
) AS t1
LEFT JOIN price_trading
ON price_trading.timestamp = t1.timestamp
AND price_trading.pair_name = t1.profit_fee_pair
LEFT JOIN zipped_fee
ON zipped_fee.timestamp = t1.timestamp
WHERE zipped_fee.timestamp IS NULL
AND t1.profit_fee_pair != 'BNBBNB'

并且需要4秒多才能看到结果。甚至只有 3 行。

+---------------------+------------+----------+------------+-------------+-----------------+-------------+-------------+-----------+
| timestamp           | fee        | fee_unit | profit     | profit_unit | profit_fee_pair | bid_price   | ask_price   | timestamp |
+---------------------+------------+----------+------------+-------------+-----------------+-------------+-------------+-----------+
| ml75-1528598537206  | 0.00285750 | BNB      | 0.00024136 | ETH         | BNBETH          |  0.02703500 |  0.02704800 | NULL      |
| lm112-1528598537226 | 0.00570927 | BNB      | 0.00024136 | ETH         | BNBETH          |  0.02703500 |  0.02704800 | NULL      |
| lm129-1528599634045 | 0.00900000 | BNB      | 0.42718954 | USDT        | BNBUSDT         | 15.57000000 | 15.60640000 | NULL      |
+---------------------+------------+----------+------------+-------------+-----------------+-------------+-------------+-----------+
3 rows in set (4.35 sec)

我尝试添加 INDEX :

ALTER TABLE zipped_fee ADD INDEX addon_fee_buster (timestamp);
ALTER TABLE trading_fredy_fee ADD INDEX addon_fee_buster (fee_unit);

但仍然需要超过 4 秒才能完成。通常,我在 WHERE 类中根据需要创建了 INDEX 列,但这次我注意到我在 WHERE 中使用了 t1.profit_fee_pair > 条款。此列是由 IF 生成的,而不是真正的列。

更新:LEFT JOIN zipped_fee 导致性能问题。在这一行之前,一切都很好。

如何改进这个结果?谢谢。

更新 : EXPLAIN 结果

+------+-------------+-------------------+-------+-------------------------------+-------------------------------+---------+-----------------------------------------+------+---------------------------------------------------------------------+
| id   | select_type | table             | type  | possible_keys                 | key                           | key_len | ref                                     | rows | Extra                                                               |
+------+-------------+-------------------+-------+-------------------------------+-------------------------------+---------+-----------------------------------------+------+---------------------------------------------------------------------+
|    1 | PRIMARY     | <derived2>        | ALL   | NULL                          | NULL                          | NULL    | NULL                                    | 8344 | Using where                                                         |
|    1 | PRIMARY     | price_trading     | ref   | price_trading_timestamp_index | price_trading_timestamp_index | 99      | t1.timestamp                            |    9 | Using where                                                         |
|    1 | PRIMARY     | zipped_fee        | index | NULL                          | fee_buster_timestamp          | 35      | NULL                                    | 4124 | Using where; Using index; Using join buffer (flat, BNL join)        |
|    2 | DERIVED     | trading_fredy     | ref   | stormbreaker_status           | stormbreaker_status           | 2       | const                                   | 8344 | Using index condition; Using where; Using temporary; Using filesort |
|    2 | DERIVED     | trading_fredy_fee | ref   | index_trading_fredy_fee       | index_trading_fredy_fee       | 98      | robokoin_binance.trading_fredy.order_id |    1 | Using where                                                         |
+------+-------------+-------------------+-------+-------------------------------+-------------------------------+---------+-----------------------------------------+------+---------------------------------------------------------------------+

更新:SHOW CREATE TABLE

| trading_fredy | CREATE TABLE `trading_fredy` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `date` datetime NOT NULL,
  `timestamp` varchar(32) NOT NULL,
  `pair` varchar(10) NOT NULL DEFAULT '',
  `action` enum('BUY','SELL') DEFAULT NULL,
  `volume` decimal(20,8) DEFAULT NULL,
  `price` decimal(20,8) DEFAULT NULL,
  `price_cutloss` decimal(20,8) DEFAULT NULL,
  `profit` decimal(20,8) DEFAULT NULL,
  `profit_unit` varchar(4) DEFAULT NULL,
  `order_id` varchar(32) NOT NULL,
  `status` enum('OPEN','CLOSED','PENDING','LOST','NO SUBMIT','RESUBMIT','ERROR','CUT LOSS') DEFAULT NULL,
  `fee` decimal(20,8) unsigned NOT NULL,
  `profit_bnb` decimal(20,8) unsigned DEFAULT NULL,
  `robo` varchar(8) DEFAULT NULL,
  `last_checked` datetime DEFAULT NULL,
  `volume_filled` decimal(20,8) unsigned DEFAULT NULL,
  `profit_released` enum('yes','no') DEFAULT 'no',
  PRIMARY KEY (`id`),
  KEY `trading_fredy_index` (`timestamp`,`pair`,`profit_unit`,`status`,`profit_released`),
  KEY `stormbreaker_status` (`status`)
) ENGINE=InnoDB AUTO_INCREMENT=16736 DEFAULT CHARSET=utf8 |

| trading_fredy_fee | CREATE TABLE `trading_fredy_fee` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `bnb_id` int(20) unsigned NOT NULL,
  `order_id` varchar(32) NOT NULL,
  `price` decimal(20,8) NOT NULL,
  `vol` decimal(20,8) NOT NULL,
  `fee` decimal(20,8) NOT NULL,
  `fee_unit` varchar(5) NOT NULL,
  `paid` enum('yes','no') DEFAULT 'no',
  PRIMARY KEY (`id`),
  KEY `index_trading_fredy_fee` (`order_id`),
  KEY `fee_buster` (`paid`)
) ENGINE=InnoDB AUTO_INCREMENT=28768 DEFAULT CHARSET=utf8 |

| price_trading | CREATE TABLE `price_trading` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `client_name` varchar(32) DEFAULT NULL,
  `timestamp` varchar(32) DEFAULT NULL,
  `pair_name` varchar(8) DEFAULT NULL,
  `bid_price` decimal(20,8) DEFAULT NULL,
  `ask_price` decimal(20,8) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `price_trading_index` (`client_name`,`timestamp`,`pair_name`),
  KEY `price_trading_timestamp_index` (`timestamp`)
) ENGINE=InnoDB AUTO_INCREMENT=284941 DEFAULT CHARSET=utf8 |

| zipped_fee | CREATE TABLE `zipped_fee` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `client_name` varchar(32) DEFAULT NULL,
  `timestamp` varchar(32) DEFAULT NULL,
  `date` datetime DEFAULT NULL,
  `pair` varchar(10) DEFAULT NULL,
  `action` enum('BUY','SELL') DEFAULT NULL,
  `volume` decimal(20,8) DEFAULT NULL,
  `price` decimal(20,8) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fee_buster_timestamp` (`timestamp`)
) ENGINE=InnoDB AUTO_INCREMENT=3991 DEFAULT CHARSET=latin1 |

最佳答案

我发现了问题。

这是因为 zipped_feeCHARSET=latin1 而其他表有 CHARSET=utf8

一旦我运行这个命令:

ALTER TABLE zipped_fee CONVERT TO CHARACTER SET utf8;

一切正常。

关于mysql - INDEX 没有改善 sql 查询结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50780273/

相关文章:

php - PHP/MYSQL创建表/insert数据

mysql - Zend_Db_Select 带有变量赋值和子查询

php - mysql db 对所有主机连接开放

java - SQLException : Access denied for user 'whatever' @'localhost'

mysql - 转换为无符号需要很长时间

javascript - 为每个用户刷新聊天正文

mysql - 将逗号分隔字段中的 mysql 计数值分组

MySQL:优化查询以从字符串集中查找匹配的字符串

php - 通过php查询输出到xls不起作用

php - MySQL 和 PHP 从注册日期开始计算分钟和小时?