1

我有一个 MISAM MySQL DB 表,里面有数百万行,我被要求使用它,但我需要先使查询速度更快。

以前根本没有索引!我在 'type' 列上添加了一个新索引,这很有帮助,但我想知道是否还有其他列可能也是最好的索引?

这是我的创建表:

CREATE TABLE `clicks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`companyid` int(11) DEFAULT '0',
`type` varchar(32) NOT NULL DEFAULT '',
`contextid` int(11) NOT NULL DEFAULT '0',
`period` varchar(16) NOT NULL DEFAULT '',
`timestamp` int(11) NOT NULL DEFAULT '0',
`location` varchar(32) NOT NULL DEFAULT '',
`ip` varchar(32) DEFAULT NULL,
`useragent` varchar(64) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `companyid` (`companyid`,`type`,`period`),
KEY `type` (`type`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

典型的 SELECT 语句通常会按companyid,typecontextid列进行过滤。

例如:

SELECT period, count(period) as count FROM clicks WHERE contextid in (123) AND timestamp > 123123123 GROUP BY period ORDER BY timestamp ASC

或者

SELECT period, count(period) as count FROM clicks WHERE contextid in (123) AND type IN('direct') AND timestamp > 123123123 GROUP BY period ORDER BY timestamp ASC

我的问题的最后一部分是这样的:当我在上面添加索引时type大约需要 1 小时 - 如果我要添加或删除多个索引,你可以在一个查询中完成,还是必须一个接一个地完成并等待为每个完成?

谢谢你的想法。

4

5 回答 5

3

索引确实很强大,但并不像你想象的那么黑。了解 MySQL 的 EXPLAIN PLAN 功能,这将帮助您系统地找到可以改进的地方:

http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html

于 2012-05-22T16:18:21.417 回答
1

要添加哪些索引实际上取决于您的查询。您正在排序(GROUP BY)或选择(WHERE)的任何内容都是索引的良好候选者。

您可能还想看看Mysql 如何使用索引

至于添加索引的时间,如果你确定要添加多个索引,你可以做mysqldump,手动编辑.sql文件中的表结构,然后重新导入。这可能需要一段时间,但至少您可以一次完成所有更改。然而,这并不真正符合随手测试的想法......所以请谨慎使用这种方法。(我在修改多个具有相同结构的表并希望为所有表添加一些索引时已经这样做了。)

另外,我不是 100% 确定,但我认为当您添加索引时,Mysql 会使用索引创建表的副本,然后删除原始表 - 所以请确保您的服务器/分区上有足够的空间对于表格的当前大小和一些边距。

于 2012-05-22T16:19:11.520 回答
0

在我看来timestampperiod可以在WHERE子句中使用它们时对其进行索引。

也代替使用contextid in (123)使用contextid = 123和代替type IN('direct')使用type = 'direct'

于 2012-05-22T16:11:49.900 回答
0

您可以在单个查询中添加多个索引。这将总体上节省一些时间,但是在您等待整个查询完成时,该表将无法访问:

ALTER TABLE table1 ADD INDEX `Index1`('col1'),
 ADD INDEX `Index2`('col2')

关于索引,这是一个复杂的主题。但是,在 WHERE 子句中包含的具有高基数的单个列上添加索引是一个不错的起点。MySQL 将尝试为查询选择最佳索引并使用它。

为了进一步调整性能,您应该考虑multi-column indices,我看到您已经使用“companyid”索引实现了它。

为了能够一直使用到GROUP BYORDER BY子句的索引,您可能需要了解很多条件。

为了最好地利用索引,您的数据库服务器必须有足够的 RAM 来将索引完全存储在内存中,并且必须正确配置服务器以实际利用内存。

于 2012-05-22T16:43:05.283 回答
0

这是您的一个查询,分多行,因此更易于阅读。

SELECT period, count(period) as count 
FROM clicks 
WHERE contextid in (123) 
AND timestamp > 123123123 
GROUP BY period 
ORDER BY timestamp ASC

我什至不确定这是一个有效的查询。我认为您的 GROUP BY 和 ORDER BY 必须在 SQL 中匹配。我认为您必须订购count,因为 GROUP BY 将订购period

优化查询的重要部分是 WHERE 子句。在这种情况下,索引contextidtimestamp会加快查询速度。

显然,您不能索引每个 WHERE 子句。您索引最常见的 WHERE 子句。

我会一次向现有表添加一个索引。是的,它很慢。但是您应该只需要添加一次索引。

于 2012-05-22T16:14:02.100 回答