我试图在具有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'
答案 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选择最佳。