How do I add indices to MySQL tables?
我有一个非常大的mysql表,大约有15万行数据。当前,当我尝试运行时
代码运行良好,因为ID字段是主索引。然而,最近为了项目的开发,我必须通过另一个字段搜索数据库。例如
号
这个字段以前没有被索引,但是,我已经将它添加为索引,但是当我尝试运行上面的查询时,结果非常慢。解释查询显示,当我已经添加了product_id字段时,没有该字段的索引,因此查询需要20分钟到30分钟之间的任何时间返回一行。
我的完整解释结果是:
1 2 3 4
| | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+----------------------+------+---------+------+------+------------------+
| 1 | SIMPLE | table | ALL | NULL | NULL | NULL | NULL | 157211 | Using where |
+----+-------------+-------+------+----------------------+------+---------+------+------+------------------+ |
请注意,我刚刚看了一眼,id字段存储为int,而product_id字段存储为varchar可能会有所帮助。这可能是问题的根源吗?
- 你能公布完整的EXPLAIN结果吗?你确定没有索引吗?或者索引在那里,但是MySQL选择不使用它?
- 一张大桌子将有150000000张唱片。一个非常大的表有15000000000条记录。一张平均大小的桌子有15万张。供以后参考。
- 注意"或"可以使MySQL不使用索引。我有一个3或的查询,每个查询都有一个索引,运行15毫秒,总共需要25秒到超时。所以我问了3个问题,并把它们合并在一起,也花了15毫秒在50万行上。
在比较integerstrings不到MySQL。如果是的idint,去掉引号。
- 我已经使用这个精确的SQL添加了索引,但它似乎还没有"应用"到数据中,而explain查询显示该字段没有索引。
- 要用show create表检查索引吗,还是已经检查过了?
- 使用SHOW INDEXES FROM YOURTABLEdev.mysql.com/doc/refman/5.0/en/show-index.html检查是否添加了索引
- 今天我遇到了@michael描述的确切问题,解决方法是"永远不要将整数与MySQL中的字符串进行比较"。谢谢。
- @wrikken我添加了索引,并使用了命令show indexes from yourtable。它出现了,但我不认为在查询表时使用它。使用索引时是否必须更改选择查询?
- @CED只需再问一个问题(你可以在评论中用我的手柄指我):1。查询本身2。它的解释3。show create table4。关于表中有多少数据以及选择的基数的一些统计信息
- @不过,我还是解决了我的问题,谢谢你的意见。问题是安静冷静:虽然我从Java生成了100K的值到我的数据库,我的索引是在一个列设置为DATETIME。事情是所有的日期都一样!当我随机约会时,一切都很好。
- @泽尔克姆斯·埃多克斯1〔2〕为什么不呢?在这种情况下,它不是自动将字符串转换为数字吗?
- @x-yuri我亲自看到过一些情况,当它抛出错误的操作数时,会导致完全扫描。不要说这毫无意义。
- 好吧,类型转换规则说不应该发生这种情况。但我不担保。至于"毫无意义",当然,如果你自己写的话。但它产生的时候是有意义的。如果可以将变量转换为字符串并让mysql处理它,那么为什么还要适应传递的变量类型呢?
- @X-尤里,我很久以前就观察到了,不知道那是什么版本。即使您自动生成它,实现一个尊重类型的查询生成器也是有意义的。
- @CED:不使用索引的主要原因是基数和MySQL认为完整表扫描比使用索引更快,或者另一个索引可能更适合。确保您的基数定期更新(ANALYZE TABLE,如果需要的话),可能会增加它们的页面以获得更可靠的数字(以牺牲更长的计算时间为代价)。如果所有这些都失败了,而且您确实非常确定并且非常了解您的数据,那么USE / FORCE INDEX就由您自己决定了,但这意味着从那时起,您将不得不每隔x个时间检查一下它是否工作得更好。
- @我在上面回答说你可能没看见。实际上,它没有被使用(或者可能被使用了IDK)的原因是所有的"我的日期"字段都具有相同的值。我确实输入了程序化的100K值,但我没有想到这一点。
- @CED:是的,当我看到有人对一个超过5岁的评论发表评论时,只是一个路过的回答:)但是:一般来说,调试一下这个问题:如果你检查了基数,你会发现你的索引实际上是根据几个不同的值来估计的,这使得在索引中使用它确实不吸引人,考虑到你是如何填写的,这是合理的。它。所以,答案更多的是如何在一般情况下调试它,而不是在这个特定的情况下;)
- @Wrikken是的,我通常在发布旧评论之前检查用户是否有信誉点,看看他们是否容易回答。不管怎样,我得检查一下肉体,因为我不知道那是什么。谢谢你的小费。
- 在MySQL中,如果使用ALTER TABLE tbl ADD INDEX (col)而不是ALTER TABLE tbl ADD INDEX col (col),那么多次使用ALTER TABLE tbl ADD INDEX (col)将继续添加名为col_2、col_3的索引,…每次。而第二次使用ALTER TABLE tbl ADD INDEX col (col),会给ERROR 1061 (42000): Duplicate key name 'col'。
你可以使用这个语法来添加和控制一种指数(或指数的哈希树)。
你可以学习关于B树和哈希索引之间的差异……dev.mysql.com http:/ / / / /文档/恩/ index-btree-hash.html refman 5.5
- 当我看到使用show indexes时,哈希转换为btree。
- 如果我没有指定任何哈希和btree的默认值是什么?
- btree为默认值
- @rnkushwaha是因为innodb和myisam不支持hash、afaik,只有内存和ndb存储引擎支持它。
这是值得注意的,你可以多场drastically索引提高查询性能。在上述的例子,我们假设操作系统的安装是一场为唯一可查询到查找说其中= 1 = 7,然后与多柱类指数的帮助。这是一个与以下国家:
比赛应该以及如何在该指数阶的查询字段。在我的例子,应该是广义的指数(其中,在没有其他方式分类)。
- 很好,显式地命名索引可以方便地反转。
- 你能引用the index should match the order of the query fields的来源吗?
- 不幸的是,那是一个同事…
两种类型的指标,可以说:当你定义了主键,索引,MySQL将把它的默认。
解释
主关键字的索引
你必须考虑你想student_idtbl_student表的主键。
在上述声明增加主键索引值,这意味着必须是独特的、不能为空。
指定的索引
上述语句将创建一student_index与普通索引的名称。
创建唯一索引
在这里,student_unique_index是索引创建和分配到学生_ ID值必须是一个独特的指数(这里可以接受空值)。
全文期权
上面的语句将创建全文索引,你需要的是与student_fulltext_index,MySQL的MyISAM引擎。
如何删除索引?
如何检查可用的索引?
你说你有一个指数,另有解释说。然而,如果你真的继续,这就是:
如果你有一个索引在MySQL和柱,决定不使用它,因为它可以用:
"有一个索引,MySQL的查询和使用更多的认为合适的,它可以仅用一个。该解决方案是一个指数,通常如果他们正常的列生成方法多是由检索更多然后一列的值。
MySQL的决定有多去匹配的行,这是更快和tablescan认为适当者。如果这是不是一ANALYZE TABLE的情况,有时帮助。
在更复杂的查询,它决定不使用它,基于智能思想甚出巫术在查询计划的一些理由,是不是适合你的当前的要求。
在情况(2)或(3),你可以用同轴电缆将使用MySQL索引词索引的提示,如果你是好的,运行一些测试,确定它的实际性能指标,提高了使用的是你的提示。