2

等待 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_raw565,832
  • ukbm001marketing.temp_CampaignCode_raw9505
  • ukbm001marketing.temp_ContactCodes_raw39

我在命令提示行中运行了这个查询。

过去我曾使用过 Microsoft SQL Server(由我的 IS 部门设置)。我正在做我自己的项目,我有以下设置:

使用 EasyPHP12.1 安装

  • Apache/2.4.2 (Win32) PHP/5.4.6
  • 软件版本:5.5.27-log - MySQL Community Server (GPL)

笔记本电脑规格

  • 处理器:Intel(R) Core(TM) i7-2620M CPU @ 2.70ghz 2.70ghz
  • 内存:8.00 GB(7.88 GB 可用)
  • 系统 64 位 Windows 系统

系统以 50% 的 CPU 使用率运行。

我没有索引任何表。我没有给表格任何主键。此问题是否与我的系统性能有关?是数据库设计问题吗?还是mysql服务器上的设置?

非常感谢您的帮助。

4

1 回答 1

1

这绝对是一个索引问题。您正在将 3 个字段的 565.832 行计数表连接到 9505 表,而不使用任何索引。这将为您提供两个表的全表扫描,这意味着服务器确实必须从磁盘(-> slooow)获取所有这些 565832 并在内存中匹配它们。

鉴于您提供的信息有限,我认为您没有进行任何 MySQL 优化,这意味着您的 join_buffer_size 会相当小。这将导致更多的表扫描,因为 MySQL 将无法在缓冲区中存储所有内容。因此,如果您不指示 MySQL 实际使用它,那么您的 8Gb 内存对您没有任何好处。

所以基本上,在'a'和'b'表上的campaigncode、contactdate和load_date字段上创建一个多列索引,并在'a'和'c'表的contactcode字段上添加一个索引。

根据表结构(绝对是当 b 或 c 表包含许多其他未在此处列出的字段时),您甚至可以考虑将campaigncodeid 字段添加到'b' 表的索引,并将campaignid 字段添加到'b' 表的索引'c' 表。这样,MySQL 就可以使用索引来检索所有数据,而无需访问实际数据表来检索这两个字段。显然,代价是您的索引会更大。结合一些 MySQL 调整,您可以将索引保留在内存中,从而进一步加快整个过程。

于 2013-05-01T11:21:26.520 回答