使用MySQL搜索大型数据集?

时间:2010-08-02 00:43:04

标签: mysql database large-data-volumes

现在我是一名非常先进的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而不是其他数据库解决方案上重建它。

2 个答案:

答案 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以查找其中包含idjames的{​​{1}},远远快于可疑的smith。您也可以将实际单词分解为单独的表并使用单词ID,但这是一个品味问题 - 它对性能的影响将是值得怀疑的。

你可能会遇到与like '%...'类似的问题,但我之前没有看到过这种语法(如果,因为它似乎是上下文f.friend_from||f.friend_to可以是一个或另一个)。

基本上,如果您希望扩展数据库,请不要执行任何,甚至看起来像选择中的每行功能。从使用大型机数据库的人那里获取,其中8400万行大约是我们的配置表的大小: - )

并且,与所有优化问题一样,测量,不要猜测!