2011-10-08 36 views
2

我的MySQL数据库有一个表3列,使用指数与MySQL表

其strucure:

CREATE TABLE `Table` (
    `value1` VARCHAR(50) NOT NULL DEFAULT '', 
    `value2` VARCHAR(50) NOT NULL DEFAULT '', 
    `value3` TEXT NULL, 
    `value4` VARCHAR(50) NULL DEFAULT NULL, 
     `value5` VARCHAR(50) NULL DEFAULT NULL, 
     PRIMARY KEY (`value1`, `value2`) 
) 
COLLATE='utf8_general_ci' 
ENGINE=InnoDB 
ROW_FORMAT=DEFAULT 

第一和第二列是: varchar(50)

,他们都结合主键 第三列是 text,

t他表包含100多万条记录我使用的第一列它需要几分钟

搜索一个具体项目做我的搜索。

我如何索引此表以加快我的搜索速度以及使用哪种索引类型?

+1

您是否曾尝试在'value1'上添加索引? – shuniar

+1

@shuniar'PRIMARY KEY(...)'_is_索引。 – Bojangles

+0

@JamWaffles,但主键是“value1”和“value2”的组合键,而不仅仅是“value1” – shuniar

回答

5

50 + 50个字符的主键?它包含什么?你应该认为桌子是第三种常规形式吗?听起来这个关键本身可能包含一些信息,听起来像是一个警钟。

如果你可以改变你用别的东西更短,更易于管理的主键,有一些事情你可以尝试:

  • 外化文字3不同的表,由新的主键
  • 匹配分析表中,以确定相应的更优化的长度,与SELECT FROM xcve_info PROCEDURE ANALYSE()
  • 改变字段的大小,而不是50个字符,如果你能负担得起额外的空间变化VARCHAR到CHAR
  • 添加索引到value1,这可能不应该是主键的一部分

总是检查更改的性能,看看它们是否值得。

1

我可以看到,有可能会改善的事情,唯一的事情是将一个唯一索引添加到第一列。如果第一列实际上不是唯一的,这显然不起作用,并且它是否比现有的主键更有效率是有问题的。我认为这可能会有所帮助的方式是,如果第一列的唯一索引小于主键(索引扫描会更快)。

此外,您可能能够在您的第一列的部分创建一个索引,也许只有5个或10前几个字符,这可能是更有效的。

而且,删除和/或插入大量的数值后,记得运行受影响的表ANALYZE TABLE,甚至OPTIMIZE TABLE。这样,MySQL查询优化器的统计信息就会更新。

3

什么是您正在执行的实际查询?索引只会帮助您搜索前缀(或确切)匹配。例如:

SELECT * FROM Table WHERE value1='Foo%' 

会找到任何与富贵开始,并应使用指数和相对较快。另一方面:

SELECT * FROM Table WHERE value1='%Foo%' 

将不会使用索引,您将被迫执行全表扫描。如果您需要这样做,则应使用全文索引和查询:http://dev.mysql.com/doc/refman/5.5/en/fulltext-search.html

0

但是,为什么要在非唯一列上搜索唯一项目?你为什么不能根据你的主键进行查询?如果由于某种原因,你不能那么我会索引值1,你正在搜索的列。

CREATE INDEX“INDEX_NAME” ON“表”(列)

1

始终是一个坏主意,用这么长的字符串作为指标,但如果你真的需要搜索它的方式考虑你怎么样过滤查询是因为MySQL无法对索引执行类似操作,所以像WHERE value1 LIKE "%mytext%"这样的条件将永远不会使用索引,而是尝试搜索更短的字符串,以便MySQL可以将该操作转换为相等的操作。例如,使用:value1 = "XXXXX"其中“XXXXX”是该字符串的一部分。要确定比较字符串的最佳长度,请分析您的字段的选择性。

也要考虑到像(value1, value2)这样的多个字段索引不会使用第二个字段,除非第一个字段完全匹配。这不是一个糟糕的指数,只是让你知道并理解它是如何工作的。

如果还是不行的作品,另一种解决方案可能是商店值1值2在新表(表2为例)与自动增量id字段,然后从添加一个外键table2使用ID(fe my_long_id),最后在table2上创建一个索引,如:my_idx (value1, value2)。搜索将是这样的:

SELECT t1.* 
FROM 
    table2 as t2 
INNER JOIN Table as t1 ON (t1.my_long_id = t2.id) 
WHERE 
    t2.value1 = "your_string" 

确保表2具有像(value1, value2)的索引和表对(my_long_id)主索引。

作为最终建议,将AUTO_INCREMENT添加为PRIMARY KEY并将(value1,values2)添加为唯一/常规密钥。这有很大的帮助,因为B-Tree存储已排序的索引,所以使用100个字符的字符串会使您在此排序中浪费I/O。 InnoDB在插入时确定该索引的最佳位置,可能需要将一些索引移动到另一个页面,以便为新索引获得一些空间。使用自动增量值可以更轻松,更便宜,因为它永远不需要做这样的动作。