Mysql:表中有7亿条记录

Mud*_*wal 16 mysql sql performance innodb elasticsearch

我需要在Mysql表中保存大约78亿条记录.表是读写密集型的.我必须保持每小时插入率至少0.02亿条记录.虽然在桌面上搜索不应超过10秒.我们有一个UI,用户可以根据不同的colums属性进行搜索.

大多数搜索查询可以像:

  1. select * from mytable where prop1='sip:+100008521149' and prop2='asdsa' order by event_timestamp desc limit 10;

  2. select * from mytable where prop1='sip:+100008521149' order by event_timestamp desc limit 10;

  3. select * from mytable where prop2='asdsa' order by event_timestamp desc limit 10;

目前桌上有2个索引:

1- idx_1(prop1,event_timestamp)
2- idx_2(prop2,event_timestamp)
Run Code Online (Sandbox Code Playgroud)

InnoDB设置如下:

    innodb_buffer_pool_size = 70G
    innodb_log_file_size = 4G
    innodb_io_capacity=2000
    innodb_io_capacity_max=6000
    innodb_lru_scan_depth=2000
    innodb_flush_log_at_trx_commit=2
    innodb_log_buffer_size=16M
    innodb_thread_concurrency = 0
    innodb_read_io_threads = 64
    innodb_write_io_threads = 64
    innodb_autoinc_lock_mode = 2
    bulk_insert_buffer_size=33554432
    query_cache_type=1
    query_cache_size=64M
    innodb_flush_neighbors=0
    expire_logs_days=10
    max-connections=500
    long_query_time = 5
    read_buffer_size=16M
    sort_buffer_size=16M
    read_rnd_buffer_size=16M
    innodb_doublewrite = 0
    innodb_flush_method=O_DIRECT
Run Code Online (Sandbox Code Playgroud)
Machine's RAM size is 99 GB.
Run Code Online (Sandbox Code Playgroud)

一旦启动系统很快,但当记录达到2.2亿时,性能会下降很多.虽然我们使用的是LOAD INFILE,但插入速度非常慢.搜索索引参数时搜索速度非常快.看起来缓冲池是不够的.

我有几个问题:

  1. 使用此配置是否可以支持此类数据.

  2. 70亿条记录的理想和实用缓冲池大小应该是多少.

  3. DATA + INDEX规模接近150 GB,仅有2.2亿条记录.看起来我需要TB的内存.
  4. 我们正在考虑使用Master/Slave配置来使各个服务器上的读写占优势.
  5. 有没有更好的方法来设计这个解决方案?
  6. 增加更多索引可以使UI搜索更好,但增加单个索引可以将插入速度降低许多倍.

UPADTE:1

Q-表比RAM大得多,对吗?buffer_pool不能足够大 - 它必须小于ram,否则性能会受到影响.

A-RAM大小为100 GB,缓冲池为70 G.是的,数据大小太大而不是RAM.

Q-请提供SHOW CREATE TABLE; 我需要调查几个问题.(数据类型,字段大小等)

A-所有字段都是字符串类型.我们已经使用了varchar(127).PK是自动生成的id bigint(20).

问:LOAD DATA INFILE中有多少条记录?你直接加入桌子吗?LOAD多久一次?

每个文件A- 100000条记录.多个线程正在将数据从CSV文件加载到DB.在初始迁移中,我们必须连续加载它直到达到6.5亿条记录.之后频率将降低到每15分钟左右.

Q- Master + Slave:请记住,所有写操作都是在Slave上执行的.如果你有大量的读取,那么不止一个Slave会扩展读取,从而得到一些扩展.

A- 我们目前正在使用MASTER/SLAVE方法进行测试.

我们用MYISAM制作了MASTER而没有索引.MASTER将用于插入.拥有INNODB和2个索引的SLAVE.搜索将在其上执行.两者都是不同的机器,不共享RAM或CPU.该应用程序位于第三台机器上.

问:你有旋转驱动器吗?还是SSD?A-如何检查?

问:你的行似乎很大.是TEXT还是BLOB?如果是这样,SELECT*可能是一个严重的性能负担.

A-是行有50列,但数据大约在15-20列.我们无法减小数据类型的大小,因为所有字段都可以容纳任意数量的字母数字数据.所有这些都是TEXTS no BLOBS.

Ric*_*mes 5

关闭查询缓存:每次INSERT发生时,它都必须清除 QC 中的所有条目——每秒 5555 次!

query_cache_type = 0
query_cache_size = 0
Run Code Online (Sandbox Code Playgroud)

第一个查询需要INDEX(prop1, prop2, event_timestamp). (prop1 和 prop2 可以交换。)

添加该索引后,三个查询中的每个查询将接触索引中不超过 10 行,并且对数据进行不超过 10 次随机(?)提取。最坏的情况下,也只有大约 11 次磁盘命中。@Bernd 的“惰性评估”不会让它变得更好。

该表比 RAM 大得多,对吗?buffer_pool 不能设置得足够大——它必须小于 ram,否则性能会受到影响

请提供SHOW CREATE TABLE; 有几个问题我需要调查。(数据类型、字段大小等)

中有多少条记录LOAD DATA INFILE?你LOAD直接进表吗?多久一次LOAD

主站+从站:请记住,所有写入也都在从站上执行。如果您有大量读取,那么多个从属设备会将读取分散来,从而获得一定的扩展性。

你们有旋转驱动器吗?还是SSD?

你的行似乎很大。有TEXTs或吗BLOBs?如果是这样,SELECT *可能会造成严重的性能负担。


Mud*_*wal 5

我通过用Elasticsearch替换MYSQL DB来实现这个需求。它看起来非常适合快速插入率和快速搜索。此外,Lucene 的全文功能使其成为一个完美的工具。ES 最好的部分是它对硬件的要求非常低。它是水平缩放而不是垂直缩放。