簡體   English   中英

如何使插入 function mysql 查詢運行得更快?

[英]How to make an insert function mysql query run faster?

我有這個查詢有時需要超過 30 秒才能運行並導致“錯誤代碼 2013。失去與 mysql 查詢的連接”(已編輯):

INSERT INTO elogbook_get_boardid
SELECT DISTINCT
Y.`LOTID`, 
`Board_ID`, 
`Serial_Number`, 
coalesce(CASE WHEN A.`Serial_Number` = X.`board_sn` THEN 'In Use' ELSE 
A.`status` END, '') AS `Status`,
coalesce(Y.`LOT_LOCATION`,'') AS `chamber`, 
coalesce(X.`created_date`, '') AS `Start Date`, 
coalesce(Y.`BINOUT_DUE_DATE`, '') AS `Est End`, 
CURRENT_TIMESTAMP AS `Current Time` 
FROM hardware_tracking_msa.HAST_Detail A 
JOIN skynet_msa.lots_to_hast_boards X 
LEFT JOIN skynet_msa.labs_inventory Y 
ON X.`lotid` = Y.`LOTID` 
ON A.`Serial_Number` = X.`board_sn`;

我想知道如何讓它運行得更快。 它每次運行時通常只插入大約 60 行

編輯:

表說明:

'elogbook_get_boardid', 
'CREATE TABLE `elogbook_get_boardid` (
\n  `LOTID` varchar(45) DEFAULT NULL,
\n  `Board_ID` varchar(45) DEFAULT NULL,
\n  `Serial_Number` varchar(45) DEFAULT NULL,
\n  `Status` varchar(45) DEFAULT NULL,
\n  `chamber` varchar(45) DEFAULT NULL,
\n  `Start Date` varchar(45) DEFAULT NULL,
\n  `Est End` varchar(45) DEFAULT NULL,
\n  `Current Time` varchar(45) DEFAULT NULL
\n) ENGINE=InnoDB DEFAULT CHARSET=utf8'

解釋function:

Field, Type, Null, Key, Default, Extra
'LOTID', 'varchar(45)', 'YES', '', NULL, ''
'Board_ID', 'varchar(45)', 'YES', '', NULL, ''
'Serial_Number', 'varchar(45)', 'YES', '', NULL, ''
'Status', 'varchar(45)', 'YES', '', NULL, ''
'chamber', 'varchar(45)', 'YES', '', NULL, ''
'Start Date', 'varchar(45)', 'YES', '', NULL, ''
'Est End', 'varchar(45)', 'YES', '', NULL, ''
'Current Time', 'varchar(45)', 'YES', '', NULL, ''

在原始查詢(已編輯)中解釋 SELECT function:

id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra
'1', 'SIMPLE', 'X', NULL, 'ALL', NULL, NULL, NULL, NULL, '80', '100.00', 'Using temporary'
'1', 'SIMPLE', 'Y', NULL, 'eq_ref', 'PRIMARY', 'PRIMARY', '50', 'skynet_msa.X.lotid', '1', '100.00', 'Using where'
'1', 'SIMPLE', 'A', NULL, 'ALL', NULL, NULL, NULL, NULL, '1456', '100.00', 'Using where; Using join buffer (hash join)'

解釋分析:

'-> Table scan on <temporary>  (actual time=0.001..0.007 rows=80 loops=1)\n
-> Temporary table with deduplication  (cost=11716.50 rows=116480) (actual time=2.047..2.056 rows=80 loops=1)\n        
-> Filter: (convert(hardware_tracking_msa.A.Serial_Number using utf8mb4) = X.board_sn)  (cost=11716.50 rows=116480) (actual time=1.207..1.825 rows=82 loops=1)\n            
-> Inner hash join (<hash>(convert(hardware_tracking_msa.A.Serial_Number using utf8mb4))=<hash>(X.board_sn))  (cost=11716.50 rows=116480) (actual time=1.206..1.807 rows=82 loops=1)\n                
-> Table scan on A  (cost=1.91 rows=1456) (actual time=0.031..0.458 rows=1456 loops=1)\n                
-> Hash\n                    
-> Nested loop left join  (cost=61.67 rows=80) (actual time=0.069..1.042 rows=80 loops=1)\n                        
-> Table scan on X  (cost=8.67 rows=80) (actual time=0.021..0.490 rows=80 loops=1)\n                        
-> Filter: (X.lotid = Y.LOTID)  (cost=0.56 rows=1) (actual time=0.007..0.007 rows=1 loops=80)\n                            
-> Single-row index lookup on Y using PRIMARY (LOTID=X.lotid)  (cost=0.56 rows=1) (actual time=0.006..0.006 rows=1 loops=80)\n'

你有什么索引?

盡量避免JOIN ( SELECT... ) 而是嘗試直接加入該子查詢中的兩個表。

WHERE 子句暗示 X.LOTID 可能是 NULL; 它就這么宣布了嗎? (您缺少兩個CREATE TABLEs 。同時您列出了一個似乎沒有使用的表!)

這些索引可能會有所幫助:

A:  INDEX(Serial_Number,  status)
Y:  INDEX(LOTID,  BINOUT_DUE_DATE, LOT_LOCATION)
X:  INDEX(lotid)

如果lots_to_hast_boards是多對多映射表,請參閱此獲取有關索引的建議: 多對多

拼出所需的列而不是X.*

在這些被修復之后,我們可能會找到一種方法來擺脫DISTINCT (它需要對數據和排序進行額外的傳遞)。

我們需要的EXPLAINEXPLAIN SELECT...

將日期時間分成兩列通常是個壞主意。 您有哪些涉及這些列的查詢?

將日期/時間放入 VARCHAR 基本上不可能比較或訂購它們。

當我在這種咆哮時,你的身份證和數字真的是數字嗎? 如果是這樣,請使用合適的數字數據類型。

字符集/排序規則

注意CONVERT(...) 這意味着 A. Serial_Number和 B. board_sn不是相同的字符集和排序規則。 可能是放緩的原因。 “序列號”聽起來像一個 ascii 字符串; 考慮將它們都設為ascii。

暫無
暫無

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

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