從 MySQL 視圖中選擇 MAX() (2x INNER JOIN) 很慢
我想優化我的MySQL 視圖
v_booking
。目前我想知道以下問題:我的查詢
查詢 1 很慢(47.48 秒):
SELECT MAX(Snapshot_Nummer) FROM v_booking;
查詢 2 很快(0.04 秒):
SELECT MAX(Snapshot_Nummer) FROM snapshot_data;
查詢 3 很快(0.03 秒):
SELECT MAX(Snapshot_Nummer) FROM snapshot_booking;
查詢 4 很快(0.03 秒):
SELECT Snapshot_Nummer FROM v_booking ORDER BY Snapshot_Nummer DESC LIMIT 1;
就我而言,所有 4 個查詢都提供相同的結果。
我的問題
有沒有辦法通過使用MySQL 視圖
MAX()
快速直接地執行該功能?
COUNT(*)
3張表中:
snapshot_data
: 5213snapshot_booking
: 4113837booking_data
: 1484創建表
創建表`snapshot_data`( `Snapshot_Nummer` int(11) NOT NULL AUTO_INCREMENT, `Snapshot_time` 日期時間 DEFAULT NULL, 主鍵(`Snapshot_Nummer`) ) 引擎=InnoDB AUTO_INCREMENT=5214 預設字元集=utf8
創建表`snapshot_booking`( `Magic_PK` int(11) NOT NULL AUTO_INCREMENT, `Snapshot_Nummer` int(11) NOT NULL, `Action_Link` int(11) 非空, `bookingState` int(11) 預設 '0', 主鍵(`Magic_PK`), KEY `snapshot_number` (`snapshot_number`), KEY `Action_Link`(`Action_Link`), 約束`snapshot_booking_ibfk_1`外鍵(`Snapshot_Nummer`)參考`snapshot_data`(`Snapshot_Nummer`), 約束`snapshot_booking_ibfk_2`外鍵(`Action_Link`)參考`booking_data`(`Action_Link`) ) 引擎=InnoDB AUTO_INCREMENT=4113838 預設字元集=utf8
創建表`booking_data`( `Action_Link` int(11) 非空, `FaMaId` int(11) 預設為空, `BuchId` int(11) 預設為空, `MadaId` int(11) 預設為空, `StationId` int(11) 預設為空, `BOId` int(11) 預設為空, `BookingCode` int(11) 預設為空, `DatumVon` 日期時間 DEFAULT NULL, `DatumBis` 日期時間 DEFAULT NULL, `UsedBy` 日期時間 DEFAULT NULL, `UsedUntil` 日期時間 DEFAULT NULL, `UsesKM` int(11) 預設為空, `StornoKZ` tinyint(1) 預設為空, `VorgaengerBuchId` int(11) 預設為空, `AngelegtDatum` 日期時間 DEFAULT NULL, `AutostornoDatum` 日期時間 DEFAULT NULL, `ChangeDateCustomer` 日期時間 DEFAULT NULL, `WishId` int(11) 預設為空, `WagenId` int(11) 預設為空, `修復` tinyint(1)預設NULL, `FBNr` int(11) 預設為空, 主鍵(`Action_Link`), KEY `storno_index` (`StornoKZ`) ) 引擎=InnoDB 預設字元集=utf8
創建視圖
創造 算法 = 未定義 DEFINER = `汽車`@`%` SQL 安全定義器 查看`v_booking` AS 選擇 `booking_data`.`FaMaId` AS `FaMaId`, `booking_data`.`BuchId` AS `BuchId`, ing booking_data`.`MadaId` AS `MadaId`, `booking_data`.`StationId` AS `StationId`, `booking_data`.`BOId` AS `BOId`, `booking_data`.`BookingCode` AS `BookingCode`, `booking_data`.`DatumVon` AS `DatumVon`, `booking_data`.`DatumBis` AS` DatumBis`, `booking_data`.`UsedBy` AS `UsedBy`, `booking_data`.`UsedUntil` AS `UsedUntil`, `booking_data`.`UsedKM` AS `UsedKM`, `booking_data`.`StornoKZ` AS `StornoKZ`, `booking_data`.`VorgaengerBuchId` AS `VorgaengerBuchId`, `booking_data`.`AngelegtDatum` AS `AngelegtDatum`, `booking_data`.`AutostornoDatum` AS `AutostornoDatum`, `booking_data`.`ChangeDateCustomer` AS `ChangeDateCustomer`, `booking_data`.`DesiredId` AS `DesiredId`, `snapshot_data`.`Snapshot_Nummer` AS` Snapshot_Nummer`, `snapshot_data`.`snapshot_time` AS `snapshot_time` 從 ((`snapshot_booking` 加入 `booking_data` ON ((`snapshot_booking`.`Action_Link` = `booking_data`.`Action_Link`))) 加入`snapshot_data` ON ((`snapshot_booking`.`Snapshot_Nummer` = `snapshot_data`.`Snapshot_Nummer`)))
解釋選擇
查詢 1
mysql> EXPLAIN SELECT MAX(Snapshot_Nummer) FROM v_booking; +----+-------------+------------------+------------+--------+-----------------------------+-----------------+---------+------------------------------------------+------+----------+-------------+ | 編號 | 選擇類型 | 表| 隔斷 | 類型 | 可能的鍵 | 關鍵 | key_len | 參考 | 行 | 過濾 | 額外 | +----+-------------+------------------+------------+--------+-----------------------------+-----------------+---------+------------------------------------------+------+----------+-------------+ | 1 | 簡單 | 快照數據 | 空 | 索引 | 初級 | 初級 | 4 | 空 | 5213 | 100.00 | 使用索引 | | 1 | 簡單 | 快照預訂 | 空 | 參考 | Snapshot_Nummer,Action_Link | Snapshot_Nummer | 4 | carsharing.snapshot_data.Snapshot_Nummer | 第797章 100.00 | 空 | | 1 | 簡單 | 預訂數據 | 空 | eq_ref | 初級 | 初級 | 4 | carsharing.snapshot_booking.Action_Link | 1 | 100.00 | 使用索引 | +----+-------------+------------------+------------+--------+-----------------------------+-----------------+---------+------------------------------------------+------+----------+-------------+ 3 行,1 個警告(0.04 秒)
查詢 2
mysql> EXPLAIN SELECT MAX(Snapshot_Nummer) FROM snapshot_data; +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ | 編號 | 選擇類型 | 表| 隔斷 | 類型 | 可能的鍵 | 關鍵 | key_len | 參考 | 行 | 過濾 | 額外 | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ | 1 | 簡單 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 選擇優化掉的表 | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ 1 行,1 個警告(0.03 秒)
查詢 3
mysql> EXPLAIN SELECT MAX(Snapshot_Nummer) FROM snapshot_booking; +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ | 編號 | 選擇類型 | 表| 隔斷 | 類型 | 可能的鍵 | 關鍵 | key_len | 參考 | 行 | 過濾 | 額外 | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ | 1 | 簡單 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 空 | 選擇優化掉的表 | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ 1 行,1 個警告(0.04 秒)
查詢 4
mysql> EXPLAIN SELECT Snapshot_Nummer FROM v_booking ORDER BY Snapshot_Nummer DESC LIMIT 1; +----+-------------+------------------+------------+--------+-----------------------------+-----------------+---------+------------------------------------------+------+----------+-------------+ | 編號 | 選擇類型 | 表| 隔斷 | 類型 | 可能的鍵 | 關鍵 | key_len | 參考 | 行 | 過濾 | 額外 | +----+-------------+------------------+------------+--------+-----------------------------+-----------------+---------+------------------------------------------+------+----------+-------------+ | 1 | 簡單 | 快照數據 | 空 | 索引 | 初級 | 初級 | 4 | 空 | 1 | 100.00 | 使用索引 | | 1 | 簡單 | 快照預訂 | 空 | 參考 | Snapshot_Nummer,Action_Link | Snapshot_Nummer | 4 | carsharing.snapshot_data.Snapshot_Nummer | 第797章 100.00 | 空 | | 1 | 簡單 | 預訂數據 | 空 | eq_ref | 初級 | 初級 | 4 | carsharing.snapshot_booking.Action_Link | 1 | 100.00 | 使用索引 | +----+-------------+------------------+------------+--------+-----------------------------+-----------------+---------+------------------------------------------+------+----------+-------------+ 3 行,1 個警告(0.04 秒)
索引
mysql> 從快照數據中顯示索引; +---------------+------------+----------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | 表 | 非唯一 | 鍵名 | Seq_in_index | 列名 | 整理 | 基數| 子部分 | 包裝 | 空 | 索引類型 | 評論 | 索引評論 | +---------------+------------+----------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | 快照數據 | 0 | 初級 | 1 | Snapshot_Nummer | 一個 | 5213 | 空 | 空 | | BTREE | | | +---------------+------------+----------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 1 行成組(0.04 秒)
mysql> 從快照預訂中顯示索引; +------------------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | 表 | 非唯一 | 鍵名 | Seq_in_index | 列名 | 整理 | 基數| 子部分 | 包裝 | 空 | 索引類型 | 評論 | 索引評論 | +------------------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | 快照預訂 | 0 | 初級 | 1 | 魔法_PK | 一個 | 3959571 | 空 | 空 | | BTREE | | | | 快照預訂 | 1 | Snapshot_Nummer | 1 | Snapshot_Nummer | 一個 | 4969 | 空 | 空 | | BTREE | | | | 快照預訂 | 1 | 行動_連結 | 1 | 行動_連結 | 一個 | 1405 | 空 | 空 | | BTREE | | | +------------------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 3 行(0.03 秒)
mysql> 從 booking_data 顯示索引; +--------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | 表 | 非唯一 | 鍵名 | Seq_in_index | 列名 | 整理 | 基數| 子部分 | 包裝 | 空 | 索引類型 | 評論 | 索引評論 | +--------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | 預訂數據 | 0 | 初級 | 1 | 行動_連結 | 一個 | 第1484章 空 | 空 | | BTREE | | | | 預訂數據 | 1 | storno_index | 1 | 斯托諾KZ | 一個 | 1 | 空 | 空 | 是 | BTREE | | | +--------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 2 行(0,03 秒)
非常感謝你!
更新 1
Gerard H. Pille 的建議:
mysql> 顯示來自 snapshot_booking 的索引; +------------------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | 表 | 非唯一 | 鍵名 | Seq_in_index | 列名 | 整理 | 基數| 子部分 | 包裝 | 空 | 索引類型 | 評論 | 索引評論 | +------------------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | 快照預訂 | 0 | 初級 | 1 | 魔法_PK | 一個 | 3959571 | 空 | 空 | | BTREE | | | | 快照預訂 | 1 | Snapshot_Nummer | 1 | Snapshot_Nummer | 一個 | 4969 | 空 | 空 | | BTREE | | | | 快照預訂 | 1 | 行動_連結 | 1 | 行動_連結 | 一個 | 1405 | 空 | 空 | | BTREE | | | +------------------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 3 行(0.03 秒) mysql> ALTER TABLE snapshot_booking ADD INDEX snapshot_nummer_action_link_index(Snapshot_Nummer, Action_Link); 查詢正常,0 行受影響(7.83 秒) 記錄:0 重複:0 警告:0 mysql> 顯示來自 snapshot_booking 的索引; +------------------+------------+-----------------------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | 表 | 非唯一 | 鍵名 | Seq_in_index | 列名 | 整理 | 基數| 子部分 | 包裝 | 空 | 索引類型 | 評論 | 索引評論 | +------------------+------------+-----------------------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | 快照預訂 | 0 | 初級 | 1 | 魔法_PK | 一個 | 3959571 | 空 | 空 | | BTREE | | | | 快照預訂 | 1 | 行動_連結 | 1 | 行動_連結 | 一個 | 1405 | 空 | 空 | | BTREE | | | | 快照預訂 | 1 | snapshot_nummer_action_link_index | 1 | Snapshot_Nummer | 一個 | 5363 | 空 | 空 | | BTREE | | | | 快照預訂 | 1 | snapshot_nummer_action_link_index | 2 | 行動_連結 | 一個 | 3960314 | 空 | 空 | | BTREE | | | +------------------+------------+-----------------------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 4 行(0.04 秒) mysql> EXPLAIN SELECT MAX(Snapshot_Nummer) FROM v_booking; +----+-------------+------------------+------------+--------+-----------------------------------------------+-----------------------------------+---------+------------------------------------------+------+----------+-------------+ | 編號 | 選擇類型 | 表| 隔斷 | 類型 | 可能的鍵 | 關鍵 | key_len | 參考 | 行 | 過濾 | 額外 | +----+-------------+------------------+------------+--------+-----------------------------------------------+-----------------------------------+---------+------------------------------------------+------+----------+-------------+ | 1 | 簡單 | 快照數據 | 空 | 索引 | 初級 | 初級 | 4 | 空 | 5213 | 100.00 | 使用索引 | | 1 | 簡單 | 快照預訂 | 空 | 參考 | Action_Link,snapshot_nummer_action_link_index | snapshot_nummer_action_link_index | 4 | carsharing.snapshot_data.Snapshot_Nummer | 第738章 100.00 | 使用索引 | | 1 | 簡單 | 預訂數據 | 空 | eq_ref | 初級 | 初級 | 4 | carsharing.snapshot_booking.Action_Link | 1 | 100.00 | 使用索引 | +----+-------------+------------------+------------+--------+-----------------------------------------------+-----------------------------------+---------+------------------------------------------+------+----------+-------------+ 3 行,1 個警告(0.06 秒) mysql> 從 v_booking 中選擇 MAX(Snapshot_Nummer); +----------------------+ † MAX(Snapshot_Number) | +----------------------+ | 5213 | +----------------------+ 1 排成套(4,64 秒)
在 snapshot_booking(snapshot_nummer、action_link)上創建一個組合索引。刪除 snapshot_booking.snapshot_nummer 上的索引。這將避免讀取 snapshot_booking 表,讀取索引就足夠了。
由於這聽起來像是
snapshot_booking
其他兩個表之間的多:多關係,因此沒有真正需要PRIMARY KEY(Magic_id)
. 擺脫它並用(snapshot_nummer, action_link)
Gerard 建議的複合索引替換它。如有必要,也有規律
INDEX
地走另一條路:(action_link, snapshot_nummer)
。如果您有任何關於 的查詢bookingState
,則讓其在兩個訂單之間做出決定——讓 PK 使其對該列更有效,然後INDEX
為相反的情況設置一個。
INT
是4個字節,範圍很大。如果儲存的值不是那麼大,請考慮將大小縮小到,例如SMALLINT UNSIGNED
(2 個字節,範圍:0..65K)。等等。一切都是真的
NULLable
嗎?將一些東西更改為NOT NULL
.為什麼
snapshot_data
存在?它只是從 id 到日期時間的映射?為什麼不使用其他表中的日期時間而不是 id?