我想优化这个SQL查询

时间:2014-08-26 06:15:05

标签: mysql

我有这样的查询:

DELIMITER $$

USE `kpbaru`$$

DROP PROCEDURE IF EXISTS `getAllUmurPegawai`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `getAllUmurPegawai`(IN id_user VARCHAR(20),i_tahun INT)
BEGIN
    DECLARE currdate INT;
    DECLARE birthdate INT;
    DECLARE numRows INT;
    DECLARE numIteration INT;
    DECLARE tempMonth INT;
    DECLARE umur INT;
    SET numRows = (SELECT COUNT(*) FROM pegawai);
    SET numIteration = 1;

    WHILE numIteration <= numRows DO
        SET currdate = i_tahun; 
        SET birthdate = (SELECT EXTRACT(YEAR FROM (SELECT TGL_LAHIR FROM pegawai WHERE INDEXING = numIteration AND ID_USER=id_user)));
        SET umur = currdate - birthdate;
        SET tempMonth = (SELECT EXTRACT(MONTH FROM (SELECT TGL_LAHIR FROM pegawai WHERE INDEXING = numIteration AND ID_USER=id_user)));
        IF umur < 56 THEN
            UPDATE pegawai SET pegawai.STATUS_PEGAWAI='Belum Pensiun',pegawai.BULAN_PENSIUN=tempMonth,STATUS_PENSIUN=1 WHERE pegawai.INDEXING = numIteration AND ID_USER=id_user;
        ELSE 
            IF umur = 56 THEN
                UPDATE pegawai SET pegawai.STATUS_PEGAWAI='Pensiun',pegawai.BULAN_PENSIUN=tempMonth,STATUS_PENSIUN=1 WHERE pegawai.INDEXING = numIteration AND ID_USER=id_user;
            ELSE 
                UPDATE pegawai SET pegawai.STATUS_PEGAWAI='Pensiun',pegawai.BULAN_PENSIUN=tempMonth,STATUS_PENSIUN=0 WHERE pegawai.INDEXING = numIteration AND ID_USER=id_user; 
            END IF;
        END IF;
        SET numIteration = numIteration + 1;
    END WHILE;
END$$

DELIMITER ;

我想优化此查询,因为此查询将搜索eeach人员中的每个年龄段。如果我们有大数据(> 1000行),则此查询运行速度非常慢。有谁知道如何优化它?

我尝试过这样的查询:

UPDATE pegawai AS p LEFT JOIN(SELECT INDEXING, CAST(CASE WHEN (i_tahun - EXTRACT(YEAR FROM(SELECT TGL_lAHIR FROM pegawai WHERE ID_USER=id_user))) < 56 THEN 'Belum Pensiun' ELSE 'Pensiun' END AS VARCHAR(20))AS statusPegawai, EXTRACT(MONTH FROM(SELECT TGL_LAHIR FROM pegawai WHERE ID_USER=id_user))AS bulanPensiun, CAST(CASE WHEN (i_tahun - EXTRACT(YEAR FROM(SELECT TGL_lAHIR FROM pegawai WHERE ID_USER=id_user))) <= 56 THEN 1 ELSE 0 END AS INT)AS statusPensiun FROM pegawai WHERE ID_USER=id_user GROUP BY INDEXING)AS m
    ON p.ID_USER = m.ID_USER
    SET p.STATUS_PEGAWAI = m.statusPegawai, p.BULAN_PENSIUN = m.bulanPensiun, p.STATUS_PENSIUN = m.statusPensiun
    WHERE p.ID_USER = id_user;

但它仍然是错误的。这里的错误是:

查询:

CREATE DEFINER=`root`@`localhost` PROCEDURE `getAllUmurPegawai`(in id_user varchar(20),i_tahun int) BEGIN  DECLARE currdate INT;...
  

错误代码:1064   您的SQL语法有错误;查看与您的MySQL服务器版本对应的手册,以便在#var;(var)(20)附近使用正确的语法作为statusPegawai,extract(月份来自(选择TGL_LAHIR来自pegawai w&#39;第29行)

解决方案将是apreciated! :d

2 个答案:

答案 0 :(得分:0)

您无法转而varchar使用char

来自mysql documentation

The CONVERT() and CAST() functions take an expression of any type and produce a result value of a specified type. 

The type for the result can be one of the following values: 

- BINARY[(N)]

- CHAR[(N)]

- DATE

- DATETIME

- DECIMAL[(M[,D])]

- SIGNED [INTEGER]

- TIME

- UNSIGNED [INTEGER] 

答案 1 :(得分:0)

如果我正确地阅读您的查询,我认为您可以在一个用户的更新声明中执行此操作: -

UPDATE pegawai
SET STATUS_PEGAWAI = IF(i_tahun - YEAR(TGL_LAHIR) < 56, 'Belum Pensiun', 'Pensiun'),
BULAN_PENSIUN = MONTH(TGL_LAHIR),
STATUS_PENSIUN = IF(i_tahun - YEAR(TGL_LAHIR) <= 56, 1, 0)
WHERE ID_USER=id_user