简体   繁体   中英

How to make an insert function mysql query run faster?

I have this query that sometimes takes more than 30 seconds to run and results in "error code 2013. lost connection to mysql query" (EDITED):

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`;

I want to know how to make it run faster. It usually only inserts around 60 rows every time it is run

Edited:

table description:

'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'

Explain 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, ''

EXPLAIN SELECT function in the original query (EDITED):

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)'

EXPLAIN ANALYZE:

'-> 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'

What indexes do you have?

Try to avoid JOIN ( SELECT... ) ; instead try to join directly to the two tables in that subquery.

The WHERE clause is implying that X.LOTID might be NULL; it it so declared? (You are missing two CREATE TABLEs . Meanwhile you listed a table that does not seem to be used!)

These indexes may help:

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

If lots_to_hast_boards is a many-to-many mapping table, see this for advice on indexing: Many-to-many

Spell out the columns needed instead of X.* .

After those are fixed, we may find a way to get rid of DISTINCT (which takes an extra pass over the data and a sort).

The EXPLAIN we need is EXPLAIN SELECT...

Splitting a date time into two columns is usually a bad idea. What queries do you have that involve those columns?

Putting dates/times into VARCHAR makes it essentially impossible to compare or order them.

While I am on this kind of rant, are your ids and numbers really numeric? If so, use a suitable numeric datatype.

Character set / Collation

Notice the CONVERT(...) . It imples that A. Serial_Number and B. board_sn are no the same character set and collation. This may be the cause of the slowdown. A "serial number" sounds like an ascii string; consider making them both ascii.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM