MySql查询和表优化

时间:2011-02-15 06:48:19

标签: mysql

我试图在具有500K记录的表上运行以下简单查询。

SELECT COUNT(*) AS impressionCount
            FROM impression
            WHERE 0 = 0
                AND impressionObjectId1 = 'C69A54B8-B828-E2E4-2319A93011DF4120'
                AND impressionObjectId2 = '1';

此查询需要10秒才能运行。我尝试为impressionObjectId1和impressionObjectId2列创建单独的索引,以及使用两者的复合索引。复合材料运作良好一段时间,但现在它也很慢。

这是我的表结构:

DROP TABLE IF EXISTS `impression`;
CREATE TABLE `impression` (
  `impressionId` varchar(50) NOT NULL,
  `impressionObjectId1` varchar(50) NOT NULL,
  `impressionObjectId2` varchar(50) default NULL,
  `impressionStampDate` datetime NOT NULL,
  PRIMARY KEY  (`impressionId`),
  KEY `IX_object` (`impressionObjectId1`,`impressionObjectId2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC COMMENT='InnoDB free: 191488 kB';

任何建议都将不胜感激。感谢

编辑:添加EXPLAIN时,这是输出:

1, 'SIMPLE', 'impression', 'ref', 'IX_object', 'IX_object', '105', 'const,const', 304499, 'Using where; Using index'

3 个答案:

答案 0 :(得分:0)

如果您反复运行完全查询,则可以缓存结果。每次使用impressionObjectId1 = 'C69A54B8-B828-E2E4-2319A93011DF4120' AND impressionObjectId2 = '1'插入表格,然后递增一个计数器,每次删除时,递减计数器。

如果你的查询的uniqe案例相对较少,那么这将是一个很好的性能助推器,虽然它不如数据完整性好,必须谨慎使用。

答案 1 :(得分:0)

为VARCHAR字段创建索引时,使用col_name(X)语法仅在前X个字符上创建索引通常很有帮助。

索引以这种方式更有效,假设字段的前X个字符足以区分行(取决于您在那里的数据类型)。如果您的列包含GUID(如示例的第1列)或非常短的文本(如第2列),则仅为前10个字符创建索引可以真正提高性能。

答案 2 :(得分:0)

我在你的解释中注意到你的'ROWS'值非常高。关于结果集中应该有多少行? (注意,解释中的ROWS是必须搜索以查找结果集的行数,而不是结果集中的行数)

您可以改变索引的顺序并获得一些效率。

通常,您希望将最具选择性的列放在索引中,以便可能匹配的行数最小。

这是找到最具选择性的专栏的一个很好的技巧:

SELECT SUM(impressionObjectId1 = 'C69A54B8-B828-E2E4-2319A93011DF4120'),
       SUM(impressionObjectId2 = '1')
            FROM impression;

最具选择性的列将具有最低的SUM值。将该列放在索引中。

你也可以创建2个索引,一个与另一个相反,让MySQL选择最佳。