现在我是一名非常先进的PHP开发人员,并且对小型MySQL集很了解,但是我现在正在为我最近加入的初创公司构建一个大型基础架构,他们的服务器每个都会推送大约100万行数据使用他们庞大的服务器功能和以前的架构。
我需要知道在数据库大小为394.4千兆字节的情况下搜索大型数据集(目前其为8490万行)的最佳方法是什么。它使用Amazon RDS托管,因此它没有任何停机或缓慢,只是我想知道什么是内部访问大型数据集的最佳方式。
例如,如果我想搜索8400万行的数据库,则需要6分钟。现在,如果我直接请求特定的ID或标题,它将立即提供。那么我将如何搜索大型数据集。
只是提醒您,通过传入一个变量来快速通过数据库查找信息,但在搜索时执行速度非常慢。
MySQL查询示例:
SELECT u.*, COUNT(*) AS user_count, f.* FROM users u LEFT JOIN friends f ON u.user_id=(f.friend_from||f.friend_to) WHERE u.user_name LIKE ('%james%smith%') GROUP BY u.signed_up LIMIT 0, 100
84米行以下的查询速度非常慢。具体47.41秒执行此查询独立,任何想法家伙?
所有我需要的是挑战排序,我将能够得到漂移。另外,我知道MySQL对于大型数据集以及类似Oracle或MSSQL的东西不是很好,但是我被告知此时在MySQL而不是其他数据库解决方案上重建它。
答案 0 :(得分:2)
LIKE
非常缓慢:
除非您的LIKE
表达式以常量开头,否则将不使用索引。
E.g。 LIKE ('james%smith%')
很好,LIKE ('%james%smith%')
不适合编制索引。您的示例不会在“user_name
”字段中使用任何索引。
与常规运营商相比,字符串匹配是复杂的(algorythmically)业务。
要解决:
如果您可以使用该字段的索引,请确保LIKE
表达式以常量开头,而不是通配符。
如果搜索整个单词,请考虑制作索引表(在“索引”一词的文献/库上下文中,而不是数据库索引上下文)。或者子串查找表,如果搜索随机经常重复的子串。
E.g。如果所有用户名都是“FN LN”或“LN,FN”形式 - 将它们拆分并在字典表中存储名字和/或姓氏,在查询中连接到该表(并进行直接相等)。
答案 1 :(得分:1)
LIKE ('%james%smith%')
避免像瘟疫这样的事情。一般的DBMS无法优化它们。
正确的方法是在插入或更新数据时计算这样的内容(名字和姓氏),以便在所有读数中分摊成本。这可以通过添加两个新列(索引)和使用插入/更新触发器来完成。
或者,如果您想要列中的所有字,请让触发器将数据分解为单词,然后使用应用程序级索引表来查找相关记录,例如:
main_table:
id integer primary key
blah blah blah
text varchar(60)
appl_index:
id index
word varchar(20)
primary key (id,word)
index (word)
然后,您可以查询appl_index
以查找其中包含id
和james
的{{1}},远远快于可疑的smith
。您也可以将实际单词分解为单独的表并使用单词ID,但这是一个品味问题 - 它对性能的影响将是值得怀疑的。
你可能会遇到与like '%...'
类似的问题,但我之前没有看到过这种语法(如果,因为它似乎是上下文f.friend_from||f.friend_to
可以是一个或另一个)。
基本上,如果您希望扩展数据库,请不要执行任何,甚至看起来像选择中的每行功能。从使用大型机数据库的人那里获取,其中8400万行大约是我们的配置表的大小: - )
并且,与所有优化问题一样,测量,不要猜测!