php—对数百万行执行10亿次查询的最快方法

o3imoua4  于 2021-06-24  发布在  Mysql
关注(0)|答案(1)|浏览(516)

我正在运行一个php脚本,它在一个相对较大的mysql示例中搜索一个包含数百万行的表,以便在一列中找到“糖尿病”之类的术语 description 上面有全文索引。然而,一天之后,我只通过了几百个查询,所以我的方法似乎永远不会奏效。中的条目 description 列的平均长度为1000个字符。
我在想我的下一步行动,我有几个问题:
我的mysql表中有一些不需要的列没有被查询。移除这些会影响性能吗?
我假设在本地运行而不是在rds上运行它将显著提高性能?我有一个像样的macbook,但我选择rds因为成本不是问题,我试着在一个比我的macbook更好的示例上运行。
使用像go这样的编译语言而不是php会比测试示例中的5-10倍boost报告做得更多吗?也就是说,考虑到我的任务,有没有理由认为静态语言可以产生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。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 .

6yjfywim

6yjfywim1#

跟进以上关于并发查询的评论。
如果查询需要30秒才能执行,那么客户端应用程序使用的编程语言将不会产生任何影响。
我有点怀疑这个查询是否真的需要1到30秒才能执行。我测试了mysql全文搜索,发现即使在我的笔记本电脑上,搜索也不到1秒。看我的演讲https://www.slideshare.net/billkarwin/practical-full-text-search-with-my-sql
可能不是查询花费了这么长时间,而是您编写的代码提交了查询。你的代码还在做什么?
如何衡量查询性能?你在使用mysql的查询分析器吗?看到了吗https://dev.mysql.com/doc/refman/5.7/en/show-profile.html 这将有助于隔离mysql执行查询所需的时间,以便您可以比较其余php代码运行所需的时间。
使用php将是单线程的,所以一次只能运行一个查询,串行地运行。您正在使用的rds示例有40个cpu核,因此您应该能够一次处理多个并发查询。但每个查询都需要由自己的客户机运行。
因此,一个想法是将输入的搜索词分成至少40个子集,并针对每个子集运行php搜索代码。mysql应该能够很好地运行并发查询。也许会有一点开销,但并行执行会大大弥补这一点。
您可以手动将搜索词拆分为单独的文件,然后使用每个文件作为输入运行php脚本。这将是解决这个问题的直接方法。
但要真正专业化,就要学会使用gnu parallel这样的工具来运行40个并发进程,并在这些进程上自动分割输入。

相关问题