MySQL索引帮助——哪个更快?

标签 mysql database indexing database-performance

我正在处理的事情:

我有一个使用 ActiveCollab 的项目2,数据库结构对我来说是新的——几乎所有的东西都存储到 project_objects 表中,并且具有递归的层次关系:

  • 记录 1234 可能是 type“Ticket”,parent_id 为 123
  • 记录 123 可能是 type“类别”,parent_id 为 12
  • 记录 12 可能是类型“里程碑”等等。

目前此表中有超过 450,000 条记录,代码中的许多查询都引用了 name 字段,该字段没有索引。示例值可能是 DesignDevelopment

这可能是一个示例查询:

SELECT * FROM project_objects WHERE type = "Ticket"和 name = "Design"

我的问题:

我有一个查询耗时超过 12-15 秒,我感觉是从那里开始的 name 列缺少索引,需要全文搜索。我对索引的理解是,如果我在 name 字段中添加一个索引,它会加快读取速度,但会减慢插入和更新速度。每次添加或更新记录时,索引是否需要完全重建,还是只是更改/附加?如果这意味着大大减慢依赖于更快写入的代码库的其他部分,我不想使用索引优化此查询。

我的问题:

假设每天 100 次读取和 100 次写入,对于 MySQL 来说,这更有可能是一个更快的过程——在没有索引的情况下在上面的表上执行上面的查询,或者每次添加记录时都必须重建索引?

我没有开始运行基准测试的知识或权限,但我想向客户提供一个建议,而不是听起来完全是新手。谢谢!

编辑:这是表格:

'CREATE TABLE `project_objects` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `source` varchar(50) DEFAULT NULL,
  `type` varchar(30) NOT NULL DEFAULT ''ProjectObject'',
  `module` varchar(30) NOT NULL DEFAULT ''system'',
  `project_id` int(10) unsigned NOT NULL DEFAULT ''0'',
  `milestone_id` int(10) unsigned DEFAULT NULL,
  `parent_id` int(10) unsigned DEFAULT NULL,
  `parent_type` varchar(30) DEFAULT NULL,
  `name` varchar(150) DEFAULT NULL,
  `body` longtext,
  `tags` text,
  `state` tinyint(4) NOT NULL DEFAULT ''0'',
  `visibility` tinyint(4) NOT NULL DEFAULT ''0'',
  `priority` tinyint(4) DEFAULT NULL,
  `created_on` datetime DEFAULT NULL,
  `created_by_id` smallint(5) unsigned NOT NULL DEFAULT ''0'',
  `created_by_name` varchar(100) DEFAULT NULL,
  `created_by_email` varchar(100) DEFAULT NULL,
  `updated_on` datetime DEFAULT NULL,
  `updated_by_id` smallint(5) unsigned DEFAULT NULL,
  `updated_by_name` varchar(100) DEFAULT NULL,
  `updated_by_email` varchar(100) DEFAULT NULL,
  `due_on` date DEFAULT NULL,
  `completed_on` datetime DEFAULT NULL,
  `completed_by_id` smallint(5) unsigned DEFAULT NULL,
  `completed_by_name` varchar(100) DEFAULT NULL,
  `completed_by_email` varchar(100) DEFAULT NULL,
  `comments_count` smallint(5) unsigned DEFAULT NULL,
  `has_time` tinyint(1) unsigned NOT NULL DEFAULT ''0'',
  `is_locked` tinyint(3) unsigned DEFAULT NULL,
  `estimate` float(9,2) DEFAULT NULL,
  `start_on` date DEFAULT NULL,
  `start_on_text` varchar(50) DEFAULT NULL,
  `due_on_text` varchar(50) DEFAULT NULL,
  `workflow_status` int(4) DEFAULT NULL,
  `varchar_field_1` varchar(255) DEFAULT NULL,
  `varchar_field_2` varchar(255) DEFAULT NULL,
  `integer_field_1` int(11) DEFAULT NULL,
  `integer_field_2` int(11) DEFAULT NULL,
  `float_field_1` double(10,2) DEFAULT NULL,
  `float_field_2` double(10,2) DEFAULT NULL,
  `text_field_1` longtext,
  `text_field_2` longtext,
  `date_field_1` date DEFAULT NULL,
  `date_field_2` date DEFAULT NULL,
  `datetime_field_1` datetime DEFAULT NULL,
  `datetime_field_2` datetime DEFAULT NULL,
  `boolean_field_1` tinyint(1) unsigned DEFAULT NULL,
  `boolean_field_2` tinyint(1) unsigned DEFAULT NULL,
  `position` int(10) unsigned DEFAULT NULL,
  `version` int(10) unsigned NOT NULL DEFAULT ''0'',
  PRIMARY KEY (`id`),
  KEY `type` (`type`),
  KEY `module` (`module`),
  KEY `project_id` (`project_id`),
  KEY `parent_id` (`parent_id`),
  KEY `created_on` (`created_on`),
  KEY `due_on` (`due_on`)
  KEY `milestone_id` (`milestone_id`)
) ENGINE=InnoDB AUTO_INCREMENT=993109 DEFAULT CHARSET=utf8'

最佳答案

正如@Ray 指出的那样,不必在每次插入、更新或删除操作时都重建索引。因此,如果您只想提高此(或类似)查询的效率,请在 (name, type)(type, name) 上添加索引。

因为你已经有了单独的 (type) 索引,我会添加第一个:

ALTER TABLE project_objects 
  ADD INDEX name_type_IDX
    (name, type) ;

在繁忙的服务器上它可能需要几秒钟,但它必须完成一次,然后所有具有像您这样的条件的查询都会受益。它还可以提高其他几种仅涉及 namenametype 的查询的效率:

WHERE name = 'Design' AND type = 'Ticket'      --- your query

WHERE name = 'Design'                          --- condition on `name` only 

GROUP BY name                                  --- group by  `name`

WHERE name LIKE 'Design%'                      --- range condition on `name` only

WHERE name = 'Design'                          --- equality condition on `name`
  AND type LIKE 'Ticket%'                      --- and range condition on `type`

WHERE name = 'Design'                          --- equality condition on `name`
GROUP BY type                                  --- and group by `type`

GROUP BY name                                  --- group by  `name`
       , type                                  --- and  `type`

关于MySQL索引帮助——哪个更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14444562/

相关文章:

mysql - MAMP Mysql 服务器不工作。错误消息 2002

optimization - 优化 MongoDB 查询或索引

database - 如何从 IBM 命令行运行存储过程?

当选择区域时,PHP 从数据库填充数据

c++ - 建立索引 : Copies or pointers?

sql-server - 关于在 SQL Server 上为各种查询创建单列索引

php从mysql获取信息

需要 php 登录脚本帮助。服务器错误,请问是什么问题?

mysql - .NET MySql "Using"关闭数据读取器?

php - 使用带有对象的 php session 还是访问数据库更好?