Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在数百万行上执行10亿次查询的最快方法_Php_Mysql_Full Text Search_Amazon Rds - Fatal编程技术网

Php 在数百万行上执行10亿次查询的最快方法

Php 在数百万行上执行10亿次查询的最快方法,php,mysql,full-text-search,amazon-rds,Php,Mysql,Full Text Search,Amazon Rds,我正在运行一个PHP脚本,它搜索一个相对较大的MySQL实例,其中有一个包含数百万行的表,在一个列description中查找诸如“糖尿病”之类的术语,该列上有全文索引。然而,一天之后,我只完成了几百个查询,所以我的方法似乎永远不会起作用。description列中的条目平均长度为1000个字符 我正在想我的下一步行动,我有几个问题: 我的MySQL表中有一些不需要查询的列。删除这些会影响性能吗 我假设在本地而不是在RDS上运行此功能将显著提高性能?我有一台像样的macbook,但我选择了RDS

我正在运行一个PHP脚本,它搜索一个相对较大的MySQL实例,其中有一个包含数百万行的表,在一个列
description
中查找诸如“糖尿病”之类的术语,该列上有全文索引。然而,一天之后,我只完成了几百个查询,所以我的方法似乎永远不会起作用。
description
列中的条目平均长度为1000个字符

我正在想我的下一步行动,我有几个问题:

  • 我的MySQL表中有一些不需要查询的列。删除这些会影响性能吗

  • 我假设在本地而不是在RDS上运行此功能将显著提高性能?我有一台像样的macbook,但我选择了RDS,因为成本不是问题,我试着在一个比my macbook更好的实例上运行

  • 使用像Go这样的编译语言而不是PHP会比测试示例中的5-10x boost people报告做得更多吗?也就是说,考虑到我的任务,有没有任何理由认为静态语言可以提高100倍或更多的速度

  • 我应该将数据放在文本或CSV文件中而不是MySQL中吗?使用MySQL只是造成不必要的开销吗


  • 以下是查询:

    SELECT id 
    FROM text_table 
    WHERE match(description) against("+diabetes +mellitus" IN BOOLEAN MODE);
    
    下面是EXPLAIN的查询输出行,显示优化器正在使用全文索引:

    1   SIMPLE  text_table  fulltext    idx idx 0   NULL    1   Using where
    
    RDS实例为db.m4.10xlarge,具有160GB的RAM。InnoDB缓冲池通常占RDS实例上RAM的75%左右,这使其达到120GB

    文本表格状态为:

               Name: text_table
             Engine: InnoDB
            Version: 10
         Row_format: Compact
               Rows: 26000630
     Avg_row_length: 2118
        Data_length: 55079485440
    Max_data_length: 0
       Index_length: 247808
          Data_free: 6291456
     Auto_increment: 29328‌​568
        Create_time: 2018-01-12 00:49:44
        Update_time: NULL
         Check_time: NULL
          Collation: utf8_general_ci
           Checksum: NULL
     Create_options: 
            Comment: 
    
    这表明该表大约有2600万行,数据和索引的大小为51.3GB,但不包括FT索引

    有关FT索引的大小,请查询:

    SELECT stat_value * @@innodb_page_size 
    FROM mysql.innodb_index_stats 
    WHERE table_name='text_table' 
    AND index_name = 'FTS_DOC_ID_INDEX' 
    AND stat_name='size'
    

    FT索引的大小是
    480247808

    跟进上面关于并发查询的评论

    如果查询需要30秒才能执行,那么客户端应用程序使用的编程语言将不会有任何区别

    我有点怀疑这个查询是否真的需要1到30秒才能执行。我测试了MySQL全文搜索,发现即使在我的笔记本电脑上,搜索也只需不到1秒。看我的演讲

    可能不是查询花费了这么长时间,而是您编写的代码提交了查询。你的代码还在做什么

    您如何衡量查询性能?您正在使用MySQL的查询分析器吗?请看,这将有助于隔离MySQL执行查询所需的时间,以便您可以比较其他PHP代码运行所需的时间

    使用PHP将是单线程的,所以一次只能连续运行一个查询。您正在使用的RDS实例有40个CPU核,因此您应该能够一次执行多个并发查询。但每个查询都需要由自己的客户机运行

    因此,一个想法是将输入搜索词拆分为至少40个子集,并针对每个子集运行PHP搜索代码。MySQL应该能够很好地运行并发查询。也许会有一点开销,但并行执行将大大弥补这一点

    您可以手动将搜索词拆分为单独的文件,然后使用每个文件作为输入运行PHP脚本。这将是解决这一问题的直接方法


    但是,要想变得真正专业,请学习使用类似于运行40个并发进程的工具,并在这些进程上自动分割输入。

    请显示您的MySQL查询。我怀疑您没有使用全文索引。我还认为您正在使用PHP,但您可以只在MySQL中使用PHP,从而大大加快速度。这个问题也太广泛,太吸引人了。你是用1-query=1搜索来访问数据库的吗?您是否可以创建第二个表,其中包含所有要查询的内容,并在一个查询中查询所有内容。表上的额外列应该无关紧要,理论上,MySQL应该命中索引,而不是表。除了共享当前查询,还请共享解释。单个查询执行多长时间?如何查询每个查询,以及在查询之间执行什么操作。在PHP中存储结果(id)?你如何获得搜索词?怀疑MySQL本身就是问题所在,你的查询是错误的,我仍然不确定MySQL是适合这项工作的工具,也不确定总体上是正确的方法。您可能会发现,翻阅纯文本源文档并对每个文档进行单独分类,要比将它们全部粉碎到数据库中,对它们进行索引,然后将该索引增加10亿次快得多。这就是map-reduce类型方法在(例如Hadoop,
    xargs
    等)中工作得很好的一种方法@andrews我从未投过反对票,但我同意这是一个很好的问题