Mysql:表{7}中有7亿条记录

时间:2016-07-07 05:20:14

标签: mysql sql performance elasticsearch innodb

我需要在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;

  4. 目前桌上有2个索引:

    1- idx_1(prop1,event_timestamp)
    2- idx_2(prop2,event_timestamp)
    

    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
    
    Machine's RAM size is 99 GB.
    

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

    我几乎没有问题:

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

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

    3. DATA + INDEX规模接近150 GB,仅为0.2亿 记录。看起来我需要有TB的公羊。
    4. 我们正在考虑使用Master / Slave配置来进行读取和使用 在各自的服务器上占主导地位。
    5. 设计此解决方案还有其他更好的方法吗?
    6. 增加更多索引可以使UI搜索更好,但增加单一搜索 一个索引正在降低插入速度很多倍。
    7. 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。

3 个答案:

答案 0 :(得分:4)

关闭查询缓存:每次INSERT发生时,它必须清除质量控制中的所有条目 - 每秒5555次!

query_cache_type = 0
query_cache_size = 0

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

使用该添加的索引,三个查询中的每一个将在索引中触摸不超过10行,并且对数据进行不超过10次随机(?)提取。在最坏的情况下,这只是大约11次磁盘命中。而@ Bernd的懒惰评论'不会让它变得更好。

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

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

LOAD DATA INFILE中有多少条记录?你LOAD直接进入桌子吗?常见的是LOAD

Master + Slave:请记住,所有写操作都是在Slave上执行的。如果你有很多读取,那么不止一个Slave会传播读取,从而得到一些扩展。

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

你的行似乎很大。有TEXTs还是BLOBs?如果是这样,SELECT *可能是一个严重的性能负担。

答案 1 :(得分:3)

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

答案 2 :(得分:2)

这不是答案,但我不能在评论中格式化

你可以试试这个,看看它是否更快。所以MySQL不能只对id(主键)

的孔行进行排序
SELECT r.*
FROM (
  SELECT id
  FROM mytable
  WHERE 
      prop1='sip:+100008521149'
    AND
      prop2='asdsa'
  ORDER BY event_timestamp DESC
  LIMIT 10
) AS r
LEFT JOIN mytable m ON m.id =r.id
ORDER BY r.event_timestamp DESC;