问题
This question is in sequence of my previous Question required update same table on deletion a row.
I could write two solutions using Stored Procedure instead of trigger or nested-query .
Both use a helper function my_signal(msg).
A Stored Procedure to delete employee from Employee
Table.
- Fist Solution: use
UPDATE
rows in table, without join operation:
CREATE PROCEDURE delete_employee(IN dssn varchar(64)) BEGIN DECLARE empDesignation varchar(128); DECLARE empSsn varchar(64); DECLARE empMssn varchar(64); SELECT SSN, designation, MSSN INTO empSsn, empDesignation, empMssn FROM Employee WHERE SSN = dssn; IF (empSsn IS NOT NULL) THEN CASE WHEN empDesignation = 'OWNER' THEN CALL my_signal('Error: OWNER can not deleted!'); WHEN empDesignation = 'WORKER' THEN DELETE FROM Employee WHERE SSN = empSsn; WHEN empDesignation = 'BOSS' THEN BEGIN UPDATE Employee SET MSSN = empMssn WHERE MSSN = empSsn; DELETE FROM Employee WHERE SSN = empSsn; END; END CASE; ELSE CALL my_signal('Error: Not a valid row!'); END IF; END//
- Second solution: as I was suggested in my previous question using
INNER JOIN
CREATE PROCEDURE delete_employee(IN dssn varchar(64)) BEGIN DECLARE empDesignation varchar(128); DECLARE empSsn varchar(64); DECLARE empMssn varchar(64); SELECT SSN, designation, MSSN INTO empSsn, empDesignation, empMssn FROM Employee WHERE SSN = dssn; IF (empSsn IS NOT NULL) THEN IF (empDesignation = 'OWNER') THEN CALL my_signal('Error: OWNER can not deleted!'); END IF; UPDATE `Employee` A INNER JOIN `Employee` B ON A.SSN= B.MSSN SET B.MSSN = A.MSSN WHERE A.SSN = empSsn; DELETE FROM `Employee` WHERE SSN = empSsn; ELSE CALL my_signal('Error: Not a valid row!'); END IF; END//
I read here that using join is efficient for Efficient SELECT. But my problem includes only one table and I feel my solution(first) is much efficient than second because join will consume memory comparatively.
Please suggest me which is better and efficient, if Employee table
is sufficiently large. Which is better for me? Reason
EDIT: I checked for small table consist of 7 rows only, and both solution take same time.
mysql> CALL delete_employee(4);
Query OK, 1 row affected (0.09 sec)
I know SQL function behaves non-deterministically because table heuristics. Which choice is better? Either if you have some idea How query can be further optimised.
回答1:
After a while of thinking I am almost sure it doesn't make a difference, first solution may be even slightly slower, but in a not measurable dimension.
First intention would be, that the first solution is faster because you first fetch data by id and update only if nessesary.
But MySQL internally does nothing else in the UPDATE .. JOIN
statement, just internally and as a result of this probably more efficiently as well.
Your first solution doesn't catch a default case - what happens if I neither get WORKER
or BOSS
?
Also your execution time (0.09s) is extremely high, which can't be explained with what I know about your database so far.
Did you set any index?
EDIT:
After looking at the table structure you've posted here I have some improvement offers for the structure itself.
1. Use type int
when you are storing integer values
. The database can handle integer way more efficient
2. Why generate SSN
by yourself? Using auto_increment
on the PRIMARY KEY
is much simpler to handle and saves you a lot of work when you add new employees
ALTER TABLE `Employee`
CHANGE `SSN` `SSN` int(11) NOT NULL AUTO_INCREMENT ,
CHANGE `MSSN` `MSSN` int(11) DEFAULT NULL,
ADD KEY `KEY_Employee_MSSN` ( `MSSN` );
3. Do you use the name for lookups? If so, it needs to be unique as well
ALTER TABLE `Employee`
ADD UNIQUE KEY `UNI_KEY_Employee` ( `name` );
4. Do you have a fixed range of designations? enum forces the input to be one of the defined values
ALTER TABLE `Employee`
CHANGE `designation` `designation` ENUM( 'BOSS', 'WORKER' ) NOT NULL DEFAULT 'WORKER',
ADD KEY `KEY_Employee_designation` ( `designation` );
Final structure
mysql> EXPLAIN `Employee`;
+-------------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------------------+------+-----+---------+----------------+
| SSN | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(64) | YES | UNI | NULL | |
| designation | enum('BOSS','WORKER') | NO | MUL | WORKER | |
| MSSN | int(11) | YES | MUL | NULL | |
+-------------+-----------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
来源:https://stackoverflow.com/questions/13518890/which-update-is-faster-using-join-or-sequential