MySQL 存储过程优化
MySQL Stored Procedure Optimization
我在 Mysql 中有以下存储过程。我的列必须是动态的,以便我将行转换为列。我有一个临时的 table 来存储我需要的数据,然后我将行连接成带有 if 语句的列,但我在 mysql 中遇到内存不足错误。有什么方法可以优化我的查询以在 mysql workbench(具有 4gb Ram 的 64 位操作系统)中高效工作?
DELIMITER $$
CREATE DEFINER=`root`@`localhost`
PROCEDURE `myWordDistributionsQueryAll`(OUT myOutput text)
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS tmpWeightTable
(INDEX(word,topicName) ) ENGINE=MyISAM
AS (
SELECT wwt.topicName, t.topic_cnt as sumOfWordsInTopic,
wwt.word, wwt.wordCount,
(wwt.wordCount / t.topic_cnt) AS wordProbability
FROM weightallofwordsintopic as wwt JOIN
(SELECT topicName, sum(wordCount) AS topic_cnt
FROM weightallofwordsintopic
GROUP BY topicName
) t
ON wwt.topicName = t.topicName
);
SET @sql = '';
SELECT @sql := CONCAT(@sql,if(@sql='','',', '),temp.output)
FROM
(
SELECT
DISTINCT
CONCAT(
'SUM(IF(word = ''',
word,
''', wordProbability, 0)) AS ',
word
) as output
FROM
tmpWeightTable
) as temp;
SET @sql = CONCAT('SELECT topicName, ', @sql, ' FROM tmpWeightTable
group by topicName order by topicName asc');
SET myOutput=@sql;
END$$
DELIMITER ;
Table:
CREATE TABLE weightallofwordsintopic (
topicName varchar(200) DEFAULT NULL,
word varchar(100) DEFAULT NULL,
wordCount int(11) DEFAULT NULL,
KEY topicName_index (topicName),
KEY word_index (word)
) ENGINE=InnoDB DEFAULT CHARSET=latin5
SELECT @sql
里面的 'derived' table 不应该是
( SELECT CONCAT(
SUM(...), ...
word
) AS output
FROM tmpWeightTable
GROUP BY word )
这样就可以进行分组了,之前好像没有。
但可能还有另一个问题。那需要在里面
SELECT @list := GROUP_CONCAT(",", item)
FROM ( SELECT
CONCAT("'", word,":", SUM(wordProbability), "'") AS item
FROM tmpWeightTable
GROUP BY word
) AS z;
然后把 sql 和
放在一起
SELECT @sql := CONCAT('SELECT topicName, ', @list,
' FROM ?? group by topicName order by topicName asc');
我迷路了...请提供每个阶段的示例字符串。
我在 Mysql 中有以下存储过程。我的列必须是动态的,以便我将行转换为列。我有一个临时的 table 来存储我需要的数据,然后我将行连接成带有 if 语句的列,但我在 mysql 中遇到内存不足错误。有什么方法可以优化我的查询以在 mysql workbench(具有 4gb Ram 的 64 位操作系统)中高效工作?
DELIMITER $$
CREATE DEFINER=`root`@`localhost`
PROCEDURE `myWordDistributionsQueryAll`(OUT myOutput text)
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS tmpWeightTable
(INDEX(word,topicName) ) ENGINE=MyISAM
AS (
SELECT wwt.topicName, t.topic_cnt as sumOfWordsInTopic,
wwt.word, wwt.wordCount,
(wwt.wordCount / t.topic_cnt) AS wordProbability
FROM weightallofwordsintopic as wwt JOIN
(SELECT topicName, sum(wordCount) AS topic_cnt
FROM weightallofwordsintopic
GROUP BY topicName
) t
ON wwt.topicName = t.topicName
);
SET @sql = '';
SELECT @sql := CONCAT(@sql,if(@sql='','',', '),temp.output)
FROM
(
SELECT
DISTINCT
CONCAT(
'SUM(IF(word = ''',
word,
''', wordProbability, 0)) AS ',
word
) as output
FROM
tmpWeightTable
) as temp;
SET @sql = CONCAT('SELECT topicName, ', @sql, ' FROM tmpWeightTable
group by topicName order by topicName asc');
SET myOutput=@sql;
END$$
DELIMITER ;
Table:
CREATE TABLE weightallofwordsintopic (
topicName varchar(200) DEFAULT NULL,
word varchar(100) DEFAULT NULL,
wordCount int(11) DEFAULT NULL,
KEY topicName_index (topicName),
KEY word_index (word)
) ENGINE=InnoDB DEFAULT CHARSET=latin5
SELECT @sql
里面的 'derived' table 不应该是
( SELECT CONCAT(
SUM(...), ...
word
) AS output
FROM tmpWeightTable
GROUP BY word )
这样就可以进行分组了,之前好像没有。
但可能还有另一个问题。那需要在里面
SELECT @list := GROUP_CONCAT(",", item)
FROM ( SELECT
CONCAT("'", word,":", SUM(wordProbability), "'") AS item
FROM tmpWeightTable
GROUP BY word
) AS z;
然后把 sql 和
放在一起SELECT @sql := CONCAT('SELECT topicName, ', @list,
' FROM ?? group by topicName order by topicName asc');
我迷路了...请提供每个阶段的示例字符串。