从性能角度来看,使用 MySQL 临时表来实现频繁使用的网站功能的效率如何?

2024-03-26

我正在尝试为网站编写搜索功能,并且我决定通过以下查询使用 MySQL 临时表来处理数据输入的方法:

CREATE TEMPORARY TABLE `patternmatch`
  (`pattern` VARCHAR(".strlen($queryLengthHere)."))

INSERT INTO `patternmatch` VALUES ".$someValues

Where $someValues是一组具有布局的数据('some', 'search', 'query')- 或者基本上是用户搜索的内容。然后我搜索我的主表images基于表中的数据patternmatch像这样:

SELECT images.* FROM images JOIN patternmatch ON (images.name LIKE patternmatch.pattern)

然后,我根据每个结果与输入的匹配程度应用启发式或评分系统,并通过该启发式等显示结果。

我想知道创建临时表需要多少开销?我知道它们只存在于会话中,并且在会话结束后就会被删除,但是如果我每秒有数十万次搜索,我可能会遇到什么样的性能问题?有没有更好的方法来实现搜索功能?


您所说的完全正确,临时表仅对当前用户/连接可见。尽管如此,仍然存在一些开销和其他一些问题,例如:

  • 对于数千个搜索中的每一个,您都将创建并填充该表(并稍后删除它) - 不是每个用户,每个搜索。因为每次搜索很可能都会重新执行脚本,而“每个会话”并不意味着 PHP 会话 - 它意味着数据库会话(打开连接)。
  • 您将需要CREATE TEMPORARY TABLES特权,你might没有。
  • 尽管如此,该表确实应该具有 MEMORY 类型,它会比看起来更多地窃取您的 RAM。因为即使有 VARCHAR,MEMORY 表也使用固定长度的行存储。
  • 如果您的启发式稍后需要引用该表两次(例如SELECT xyz FROM patternmatch AS pm1, patternmatch AS pm2 ...) - 这对于 MEMORY 表来说是不可能的。

接下来,您以及数据库都会更容易添加LIKE '%xyz%'直接到您的images tables WHERE条款。它将执行相同的操作,而无需创建临时表并加入它的开销。

无论如何 - 无论你走哪条路 - WHERE 都会慢得可怕。即使您添加索引images.name你很可能需要LIKE '%xyz%'代替LIKE 'xyz%',这样索引就不会被使用。

我问的是,处理用户搜索输入的特定于会话的临时表(在搜索时创建,在会话结束时删除)是否是处理搜索功能的适当方法。

No. :)

替代方案

MySQL 有一个内置的全文搜索 http://dev.mysql.com/doc/refman/5.5/en/fulltext-natural-language.html(从 5.6 开始也适用于 InnoDB)甚至可以给你这样的分数:我强烈建议你阅读并尝试一下。您可以确信数据库比您更了解如何有效地进行搜索。

如果您打算使用 MyISAM 而不是 InnoDB,请注意一个经常被忽视的限制:全文搜索仅在结果数少于表总行数的 50% 时才返回任何内容。

您可能想要查看的其他内容,例如 Solr(对该主题本身的很好的介绍阅读将是http://en.wikipedia.org/wiki/Apache_Solr http://en.wikipedia.org/wiki/Apache_Solr)。我们公司正在使用它,效果很好,但需要相当多的学习。

Summary

当前问题本身(搜索)的解决方案是使用全文功能。

如果我每秒有数十万次搜索,我可能会遇到什么样的性能问题?有没有更好的方法来实现搜索功能?

给你一个数字,每秒 10.000 次调用已经不是“小事”了 - 每秒有数十万次搜索,你将在设置中遇到的性能问题无处不在。您将需要几台服务器、负载平衡和大量其他令人惊叹的技术垃圾。其中之一就是 Solr ;)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从性能角度来看,使用 MySQL 临时表来实现频繁使用的网站功能的效率如何? 的相关文章

随机推荐