自动检查全文索引,如果不存在则创建一个?

时间:2013-07-16 18:40:09

标签: mysql full-text-search

我知道如何添加全文索引并进行基本的布尔搜索......

ALTER TABLE products ADD FULLTEXT KEY myIndex (model, description);
SELECT * 
FROM   products 
WHERE  MATCH(model, description) AGAINST('myKeyword' in boolean mode);

但是,我想知道是否可以做这样的事情......

我希望我的SQL检查'myIndex'是否存在,如果不存在,它应该自动获取现有列名并添加全文索引(注意*代替列名):

ALTER TABLE products ADD FULLTEXT KEY myIndex (*);

此外,在搜索索引时,我是否可以再次自动获取列名,而不必手动输入(再次注意*代替列名)...

SELECT * 
FROM  products 
WHERE MATCH(*) AGAINST('myKeyword' in boolean mode);

我不知道正确的语法,但这样的事情可能吗?我一直在谷歌搜索几个小时,我很难找到答案。我知道我可以让PHP生成我需要的SQL,但我想知道这是否可以使用严格的SQL?

谢谢!

2 个答案:

答案 0 :(得分:4)

根据您的评论,您希望动态索引数据库。这通常不是一个好主意。索引削减了两种方式,它是一把双刃剑。让我解释一下。

因此,索引本质上是磁盘上的数据结构,其中包含要索引的所有值。例如,假设您有一个包含10列的1000行表,并且您索引1列,则此新索引也将包含1000个条目。它将包含该列的所有行值。然后将此索引写入磁盘,以便您可以阅读它。

下次插入新行时,必须将其插入表和索引中。更新索引列时,它必须更新表和索引。从我在您的问题中看到的内容,您希望动态索引多个列。

因此,假设您有一个相当大的表,其中包含10 000 000行和3列,您可以将所有需要索引的30 000 000个值编入索引。实际上,当您动态创建此索引时,服务器在索引表时会非常慢。此外,一旦完成,您的插入将变慢,对索引列的更新将更慢。一般的经验法则索引可以加快读取速度并减慢插入速度。

现在只是为了增加一点复杂性。您无法保证MySQL将使用新创建的索引。 MySQL使用内部统计信息来决定使用哪个索引。虽然在您的情况下这可能不是一个问题,因为您使用全文索引。您可以在MySQL中强制使用索引,但这也不是最佳方法。

如果我可以提出建议,请不要像这样优化。您正在尝试执行一种非常通用的优化方法,即在任何地方应用索引。而是启用慢查询日志并识别运行缓慢的查询。然后将这些查询与explain语句一起使用,以确定如何优化该情况。您将获得更少的索引并获得良好的读写速度平衡。

我希望这一切都有点意义。

答案 1 :(得分:2)

您可以通过以下方式检查全文索引是否存在:

SELECT DISTINCT index_name 
FROM INFORMATION_SCHEMA.STATISTICS
WHERE (table_schema, table_name) = ('mydatabase', 'products')
  AND index_type = 'FULLTEXT';

您可以通过这种方式获取该索引中的列:

SELECT column_name 
FROM INFORMATION_SCHEMA.STATISTICS
WHERE (table_schema, table_name) = ('mydatabase', 'products')
  AND index_type = 'FULLTEXT'
ORDER BY seq_in_index;

您无法使用MATCH(*)。必须拼写列,您必须将所有命名为索引中的列,并且必须按照定义索引时的顺序命名它们。


我还应该注意,针对information_schema的一些查询似乎很慢,因为InnoDB通过从磁盘读取随机页面来对表和索引进行采样。也就是说,读取元数据会导致I / O.您可以使用SET GLOBAL innodb_stats_on_metadata=0缓解此问题。另请参阅http://www.mysqlperformanceblog.com/2011/12/23/solving-information_schema-slowness/