我有這樣的MySQL查詢:MySQL的優化與分和限制查詢在觸發
SELECT MIN(v.ifr) FROM (SELECT v.ifr FROM tbl_valuation v WHERE v.stock_id = 1 ORDER BY v.created_at DESC LIMIT 19) as v;
的查詢說明:
+----+-------------+------------+------------+------+---------------+------------+---------+-------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+------+---------------+------------+---------+-------+------+----------+---------------------------------------+
| 1 | PRIMARY | <derived2> | NULL | ALL | NULL | NULL | NULL | NULL | 19 | 100.00 | NULL |
| 2 | DERIVED | v | NULL | ref | idx_stock | idx_stock | 9 | const | 2873 | 100.00 | Using index condition; Using filesort |
+----+-------------+------------+------------+------+---------------+------------+---------+-------+------+----------+---------------------------------------+
的問題是,這個查詢以及其他類似於此的在觸發器中,因此,在每次插入之前,這些查詢都會運行並更新一些值。 觸發器每分鐘激活約千次。
經過1m記錄後,速度變慢,可能是因爲mysql經歷了大約54587行。
有一種方法可以優化此查詢嗎?
這是我的觸發器:
CREATE TRIGGER BUY_WARNING_TRIG BEFORE INSERT
ON tbl_valuation
FOR EACH ROW
BEGIN
DECLARE warn_counter INT DEFAULT 0;
DECLARE min_ifr DECIMAL(17,12);
DECLARE min_lgui DECIMAL(17,12);
DECLARE stock VARCHAR(100);
IF New.ls >= New.macd THEN
SELECT MIN(v.ifr)
FROM (SELECT v.ifr FROM tbl_valuation v WHERE v.stock_id = New.stock_id ORDER BY v.created_at DESC LIMIT 9) as v INTO min_ifr;
IF New.ifr <= min_ifr THEN
SELECT MIN(v.lgui)
FROM (SELECT v.lgui FROM tbl_valuation v WHERE v.stock_id = New.stock_id ORDER BY v.created_at DESC LIMIT 9) as v INTO min_lgui;
IF New.lgui <= min_lgui THEN
SET warn_counter = warn_counter + 1;
END IF;
END IF;
SELECT MIN(v.ifr) FROM (SELECT v.ifr FROM tbl_valuation v WHERE v.stock_id = New.stock_id ORDER BY v.created_at DESC LIMIT 4) as v INTO min_ifr;
IF New.ifr <= min_ifr THEN
SELECT MIN(v.lgui)
FROM (SELECT v.lgui FROM tbl_valuation v WHERE v.stock_id = New.stock_id ORDER BY v.created_at DESC LIMIT 4) as v INTO min_lgui;
IF New.lgui <= min_lgui THEN
SET warn_counter = warn_counter + 1;
END IF;
END IF;
SELECT MIN(v.ifr) FROM (SELECT v.ifr FROM tbl_valuation v WHERE v.stock_id = New.stock_id ORDER BY v.created_at DESC LIMIT 19) as v INTO min_ifr;
IF New.ifr <= min_ifr THEN
SELECT MIN(v.lgui)
FROM (SELECT v.lgui FROM tbl_valuation v WHERE v.stock_id = New.stock_id ORDER BY v.created_at DESC LIMIT 19) as v INTO min_lgui;
IF New.lgui <= min_lgui THEN
SET warn_counter = warn_counter + 1;
END IF;
END IF;
END IF;
IF warn_counter > 0 THEN
SELECT t.stock FROM tbl_stock t WHERE t.id = New.stock_id INTO stock;
CASE warn_counter
WHEN 1 THEN INSERT INTO tbl_warning (created_at, stock, level, rate, `type`) VALUES (NOW(), stock, 'LOW', New.rate, 'BUY');
WHEN 2 THEN INSERT INTO tbl_warning (created_at, stock, level, rate, `type`) VALUES (NOW(), stock, 'MED', New.rate, 'BUY');
WHEN 3 THEN INSERT INTO tbl_warning (created_at, stock, level, rate, `type`) VALUES (NOW(), stock, 'HIGH', New.rate, 'BUY');
END CASE;
END IF;
END$$
謝謝你,這個索引增加了我的響應時間減少了一半。 – c0nf1ck