我对MySQL很新,并且已经转换了一个MSSQL查询,它可以很好地运行到MySQL,但是我发现MySQL版本最终在我的Mac上耗尽内存并停止。显然,我的转换努力有一个缺陷。 :(
我需要查看一个包含88,000行的表(CurrentPages),尝试确定其ContentBody列(LongText类型)是否包含第二个表(插件)中有300行的任何一系列值。插件表中的Mask列包含类似'%{macro%'。
的内容我使用存储过程迭代这两个表,存储任何"命中"在名为Usage。的第三个表中找到。
Create TABLE IF NOT EXISTS CurrentPages (
ContentID BIGINT(20) NOT NULL PRIMARY KEY,
SpaceKey VARCHAR(255) NULL,
PageTitle VARCHAR(255) NULL,
ViewURL VARCHAR(255) NULL,
OriginalAuthor VARCHAR(255) NULL,
LastChangedBy VARCHAR(255) NULL,
LastChangedDt VARCHAR(10) NULL,
ContentBody LONGTEXT NULL
);
Create TABLE IF NOT EXISTS Plugins (
MacroType INT(10) NOT NULL PRIMARY KEY,
PluginName VARCHAR(255) NOT NULL,
MacroName VARCHAR(255) NOT NULL,
Mask VARCHAR(255) NOT NULL,
Disposition VARCHAR(255) NOT NULL
);
Create TABLE IF NOT EXISTS Usage (
ID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
MacroType INT(10) NOT NULL,
SpaceKey VARCHAR(255) NOT NULL,
PageTitle VARCHAR(255) NOT NULL,
ViewURL VARCHAR(255) NOT NULL,
PluginName VARCHAR(255) NOT NULL,
MacroName VARCHAR(255) NOT NULL,
Disposition VARCHAR(255) NOT NULL
);
我意识到这确实是很多工作,但我认为可以用光标完成。下面是我的存储过程。在我的MySQL客户端(Navicat)由于内存不足而停止响应之前,它会将大约96,000行写入Usage表。
谁能看到我做错了什么?任何帮助将不胜感激! ;)
DELIMITER //
CREATE PROCEDURE pluginanalysis()
BEGIN
-- Declare variables used with cursor to fetch usage info
DECLARE v_macrotype INT(10) DEFAULT 0;
DECLARE v_pluginname VARCHAR(255) DEFAULT "";
DECLARE v_macroname VARCHAR(255) DEFAULT "";
DECLARE v_mask VARCHAR(255) DEFAULT "";
DECLARE v_disposition VARCHAR(255) DEFAULT "";
DECLARE v_num_rows INT(10) DEFAULT 0;
DECLARE v_loop_counter INT(10) DEFAULT 0;
DECLARE v_no_more_rows BOOLEAN;
-- Declare cursor "c" to populate Usage table with info about where macros are used
DECLARE c CURSOR FOR
SELECT MacroType, PluginName, MacroName, Mask, Disposition FROM appfire_Plugins;
-- Declare NOT FOUND handler
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET v_no_more_rows = TRUE;
-- Open cursor "c"
OPEN c;
SELECT FOUND_ROWS() INTO v_num_rows;
SELECT 'Number of rows =', v_num_rows;
get_usage_loop: LOOP
FETCH c
INTO v_macrotype,
v_pluginname,
v_macroname,
v_mask,
v_disposition;
-- Break out of the loop if there were no records or we've processed them all
IF v_no_more_rows THEN
CLOSE c;
LEAVE get_usage_loop;
END IF;
INSERT INTO Usage (SpaceKey, PageTitle, ViewURL, MacroType, PluginName, MacroName, Disposition)
SELECT SpaceKey,
PageTitle,
ViewURL,
v_macrotype,
v_pluginname,
v_macroname,
v_disposition
FROM CurrentPages
WHERE ContentBody LIKE v_mask;
SET v_loop_counter = v_loop_counter + 1;
END LOOP get_usage_loop;
-- Show both counters; they should match if all rows were processed
SELECT v_num_rows, v_loop_counter;
END //
-- Restore standard delimiter (semicolon)
DELIMITER ;
-- Now call the stored procedure
CALL pluginanalysis();
答案 0 :(得分:0)
在MySQL和SQL Server中,设置操作通常比使用游标更快。
我认为以下查询可以替换所有游标代码:
INSERT INTO Usage(SpaceKey, PageTitle, ViewURL, MacroType, PluginName, MacroName, Disposition)
SELECT cp.SpaceKey, cp.PageTitle, cp.ViewURL,
ap.macrotype, ap.pluginname, ap.macroname, ap.disposition
FROM Appfire_Plugins ap JOIN
CurrentPages cp
ON cp.ContentBody LIKE ap.mask;