首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >优化存储过程

优化存储过程
EN

Database Administration用户
提问于 2015-02-01 16:25:05
回答 1查看 73关注 0票数 0

我已经对下面的mysql存储过程进行了一些优化,但是它仍然运行得很慢:

代码语言:javascript
运行
复制
CREATE DEFINER=`xxx`@`%` PROCEDURE `testing`(IN _MONTH INT, IN _YEAR INT, IN _PRODUCTS TEXT)
BEGIN

set @_START = date(_YEAR * 10000 + _MONTH * 100 + 1); 
set @_END = date_add(date(_YEAR * 10000 + _MONTH * 100 + 1), interval 1 month);

DROP TABLE IF EXISTS ReportThreeTotal;
DROP TABLE IF EXISTS ReportThreeAbandondCalls;
DROP TABLE IF EXISTS ReportThreeSpillGain;
DROP TABLE IF EXISTS ReportThreeStamp;
DROP TABLE IF EXISTS ReportThreeResults;

CREATE TEMPORARY TABLE IF NOT EXISTS ReportThreeTotal AS (
    SELECT count(*) as 'count', DAYOFWEEK(`end`) as 'DOW' 
    FROM callstats.cdrdata_archive 
    where end >= @_START and end < @_END
    AND calling IN (
        SELECT Number FROM callstats.products WHERE products.id IN (_PRODUCTS) )
    GROUP BY DAYOFWEEK(`end`)
);

CREATE TEMPORARY TABLE IF NOT EXISTS ReportThreeAbandondCalls AS (
    SELECT count(*) as 'count', DAYOFWEEK(`end`) as 'DOW'
    FROM callstats.cdrdata_archive 
    WHERE calling IN (
        SELECT Number 
        FROM callstats.products 
        WHERE products.id IN (_PRODUCTS) ) 
    AND end >= @_START and end < @_END
    AND CAST(`duration` AS UNSIGNED) < 30 
    GROUP BY DAYOFWEEK(`end`)
);

CREATE TEMPORARY TABLE IF NOT EXISTS ReportThreeSpillGain AS (
SELECT (case when (SUM(count) is null) then 0 else SUM(count) end) as 'SPILLGAIN', DAYOFWEEK(`end`) as 'DOW'
FROM (SELECT count(*) as 'count', called, end
    FROM (
        SELECT called, calling, count(*) as 'count', end
        FROM cdrdata_archive 
        JOIN products ON Number = calling 
        WHERE end >= @_START AND end < @_END
        AND products.id IN (_PRODUCTS) 
        AND called != 'Anonymous' 
        GROUP BY called, calling, DAYOFWEEK(`end`) 
        ORDER BY `end` ASC ) 
    AS tbl1 
     GROUP BY called having count(*) > 1) 
 AS tbl2
 GROUP BY DAYOFWEEK(`end`));

CREATE TEMPORARY TABLE ReportThreeStamp(stamp text, DOW INT);
    SET @Counter = 1;
    while @Counter <= 7 do
        INSERT INTO ReportThreeStamp VALUES(TIMESTAMP_FROM_DATE(_YEAR * 10000 + _MONTH * 100 + @Counter), @Counter);
        SET @Counter=@Counter+1;
    end while;

CREATE TEMPORARY TABLE IF NOT EXISTS ReportThreeResults AS (
SELECT CONCAT('[',S.`stamp`,',', (
    case when (A.`count` = 0) 
         then 0 
         else (A.`count` / T.`count`) * 100 end),']') AS 'JSON_PERCENT',
    CONCAT('[',S.`stamp`,',',T.`count`,']') AS 'JSON_TOTAL',
    A.`DOW` as 'DOTW',
 A.`COUNT` as 'ATOTAL', T.`COUNT` as 'TOTAL',
SG.SPILLGAIN as 'GAINPER', SG.SPILLGAIN as 'SPILLPER'
FROM ReportThreeAbandondCalls A LEFT JOIN ReportThreeTotal T ON A.`DOW` = T.`DOW` LEFT JOIN ReportThreeSpillGain SG ON SG.`DOW` = A.`DOW` 
LEFT JOIN ReportThreeStamp S ON A.`DOW` = S.`DOW`);

SELECT * FROM ReportThreeResults;

DROP TABLE IF EXISTS ReportThreeTotal;
DROP TABLE IF EXISTS ReportThreeAbandondCalls;
DROP TABLE IF EXISTS ReportThreeSpillGain;
DROP TABLE IF EXISTS ReportThreeStamp;
DROP TABLE IF EXISTS ReportThreeResults;

END

end字段有一个索引集,可以提高性能。有什么想法来优化这个存储过程吗?

EN

回答 1

Database Administration用户

回答已采纳

发布于 2015-02-01 18:18:08

  • “(选择. )”优化得很差;切换到连接。
  • 创建/删除表的速度很慢,特别是在Windows上。
  • ReportThreeStamp似乎是静态的;为什么不将其构建为一个非临时表,并且只这样做一次。
  • (如果(SUM(count)为null)那么0 count(Count)结束)-> IFNULL( SUM(count),0))
  • 临时表似乎没有索引;这会导致缓慢的表扫描。建议以下语法来创建索引,同时创建和填充: create x(主键(y) )选择.
  • 桌子上有多少行?如果数以百万计的话,我们应该讨论一下“汇总表”,以及它们如何才能将处理速度提高10倍。
票数 1
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/90742

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档