2010-06-23 59 views
2

简单情况下,两列表[ID,TEXT]。文本列有1-10个单词短语。 300,000行。什么是在表上运行优化,做出如此巨大的差异?

运行查询:

SELECT * FROM row 
WHERE text LIKE '%word%' 

...把​​0.1秒。好。
因此,我创建一个第二柱,表现在有:[ID,TEXT2,TEXT2] 我制成TEXT2 = TEXT(使用UPDATE table SET TEXT2 = TEXT]

然后我再次运行关于 '%字%' 查询,并。它需要2.4秒


这让我非常非常难住了,但之后不少死胡同,我运行OPTIMIZE在桌子上,和它关系到0.2秒左右

两个问题:

  1. 有没有人知道数据结构如何在如此混乱的情况下得到自身的效果,即数据翻倍将该查询的搜索时间增加了24倍?
  2. 像这样的未索引搜索的标准是否以基础表数据结构的速度增加而不是正在搜索的实际列中的数据?

谢谢!

+0

有关数据库的一些知识是,当查询命中优化器时,它并不总是选择与数据相同的路径。我更熟悉Oracle(在SQL Server上少一点) - 都试图在查询必须与文本完全匹配的缓存中查找查询。如果它匹配,则称它为软解析,因为解析已经完成。否则,它必须做一个硬解析,然后软解析... – 2010-06-23 01:23:09

+0

如果你使用通配符启动查询键,无论如何它都要进行表扫描。 – dkretz 2010-06-23 01:45:14

+0

小马...这是OPTOMIZE作为清理数据的mySQL函数 - 我不是在讨论如何优化实际查询。 Dorifer ...是的,我知道它会进行全表扫描。问题依然存在。 – 2010-06-23 11:15:02

回答

0

听起来像你是查询缓存的受害者。第二次运行查询时(在优化之后),它已经有了缓存的答案,因此结果会立即返回。您是否尝试过搜索不同的搜索字词?试着用缓存运行查询关掉像这样:

SELECT SQL_NO_CACHE * FROM row WHERE text LIKE '%word%' 

要看看这改变的结果,或尝试搜索不同的单词,但结果同样数量,以确保您的服务器不只是返回缓存值。

+0

如果它被缓存了,它不应该像以前那样以较快的速度返回答案吗? – 2010-06-23 01:16:44

+0

需要2.4秒的查询在更新语句后发生,因此无法使用查询缓存,因为基础数据已更改。然而,优化表并不会更改基础数据,因此结果会很快恢复。我在考虑优化表命令并不重要,而且它实际上运行得更快,因为结果被缓存了,底层数据没有改变。 – Kibbee 2010-06-23 01:29:55

+0

但是OP在问为什么需要更长的时间... – 2010-06-23 01:31:41

0

它第一次进行表扫描,听起来正确的时机 - 没有涉及索引。

然后你添加了索引,mysql优化器没有注意到你在前面有一个通配符,所以它扫描整个索引以找到记录,然后需要两个更多的读取(一个到PK,然后一个从那里进入表格)以获取数据记录。

OPTIMIZE可能只是更新优化器的统计信息,所以它知道它应该再次扫描表。

+0

任何表格都没有索引。两名查询者都在按照预先扫描的方式进行全表扫描。 – 2010-06-23 11:15:20

+0

你最终的文件大小是否相同? (这是MyISAM表,对吧?)考虑到你使用的是恶性通配符查询,你到底想要解决什么问题?我猜测它会把表格从可以加载到内存中的东西和需要交换磁盘的东西转移过来,但是你可以从数据库统计中找到它。 – dkretz 2010-06-23 16:50:06

+0

运行optomize从35MB到28MB。但我不认为这是问题,因为我也尝试将VARCHAR列更改为CHAR(250)列。这使得表格大约有70MB,但与OPTOMIZE相比,它的效果相差20倍。 – 2010-06-23 23:12:51

0

我会认为这种差异是由于增加的行长度导致表在磁盘上碎片化。优化会排除这个问题,导致搜索时间恢复正常(给予或稍微)。

相关问题