运行以下查询需要等待3小时,50分钟和39.70秒才能激动或正常吗?
CREATE TABLE ukbm001marketing.CampaignHistory_v2
(
AddressId int,
CampaignId int,
CampaignTypeId int,
OpenUserId nvarchar(255),
OpenDate datetime,
CloseUserId nvarchar(255),
CloseDate datetime
);
INSERT INTO ukbm001marketing.CampaignHistory_v2
SELECT a.ContactId,
b.CampaignCodeId,
c.CampaignId,
'mballinger',
now(),
NULL,
NULL -- SELECT *
FROM
ukbm001marketing.temp_ContactHistory_grtthn2009_raw a
LEFT JOIN
ukbm001marketing.temp_CampaignCode_raw b ON a.CampaignCode = b.CampaignCode
AND a.ContactDate = b.ContactDate
AND a.Load_Date = b.Load_Date
LEFT JOIN
ukbm001marketing.temp_ContactCodes_raw c ON a.ContactCode = c.ContactCode;
查询中使用的表:
ukbm001marketing.temp_ContactHistory_grtthn2009_raw
565,832 行ukbm001marketing.temp_CampaignCode_raw
9505 行ukbm001marketing.temp_ContactCodes_raw
39 行我在命令提示行中运行了此查询。
过去我曾使用Microsoft SQL Server(由我的IS部门设置)。我正在做一个属于我自己的项目,我有以下设置:
使用EasyPHP12.1安装
笔记本电脑规格
系统以50%的CPU使用率运行。
我没有索引任何表格。我没有给表任何主键。此问题是否与我的系统性能有关?这是数据库设计问题吗?或者它是mysql服务器上的设置吗?
非常感谢您的帮助。
答案 0 :(得分:1)
这绝对是一个索引问题。您正在将3个字段上的565.832行计数表连接到9505表而不使用任何索引。这将为您提供两个表的全表扫描,这意味着服务器确实必须从磁盘( - > slooow)获取所有这些565832并在内存中匹配它们。
鉴于您提供的信息有限,我认为您没有做过任何MySQL优化,这意味着您的join_buffer_size会相当小。这将导致更多的表扫描,因为MySQL将无法将所有内容存储在缓冲区中。所以,如果你没有指示MySQL实际使用它,那么你的8Gb ram对你没有任何帮助。
所以基本上,在'a'和'b'表上的campaigncode,contactdate和load_date字段上创建一个多列索引,并在'a'和'c'表的contactcode字段上添加一个索引
根据表格结构(当b或c表包含此处未列出的许多其他字段时),您甚至可以考虑将campaigncodeid字段添加到'b'表中的索引和campaignid到'c'表上的索引。这样,MySQL就能够使用索引来检索所有数据,而不需要访问实际的数据表来检索这两个字段。显然,惩罚是你的指数会更大。结合一些MySQL调优,您可以将索引保留在内存中,从而加快整个过程。