插入/更新/删除时没有问题,{S慢级Sqlite3选择查询

时间:2016-09-11 16:18:08

标签: c++ linux sqlite

我遇到了与慢速sqlite3选择相关的问题。我在这个论坛上搜索了很多,并且已经应用​​了许多有助于我前进的建议。我假设我尝试使用sqlite的方式有一些错误,或者可能是我在编译时使用的设置。

在阅读了很多关于它的性能后,我决定在c ++中使用sqlite3。由于数据流入非常高并且服务器在交换时设置在同一位置,如果由于任何原因导致数据包处理延迟,则可能会丢包并且延迟数据包在高频率下无用 交易环境。可以存在5mbps的最小分组流,其中每个分组具有最大45字节大小。我的sqlite设置为In Memory 使用

要了解我的问题,请详细说明以下内容。

以下是服务器的详细信息:

我尝试使用Sqlite3的服务器详细信息

  • 架构:x86_64
  • CPU op-mode(s):32位,64位
  • 字节顺序:Little Endian
  • CPU:16
  • 在线CPU列表:0-15
  • 每个核心的线程:2
  • 每个插座的核心:4
  • Socket(s):2
  • NUMA节点:2
  • 供应商ID:GenuineIntel
  • CPU系列:6
  • 型号:45
  • 型号名称:Intel(R)Xeon(R)CPU E5-2643 0 @ 3.30GHz
  • 步进:7
  • CPU MHz:3400.160
  • BogoMIPS:6603.86
  • 虚拟化:VT-x
  • L1d缓存:32K
  • L1i缓存:32K
  • 二级缓存:256K
  • L3缓存:10240K
  • NUMA node0 CPU(0):0,2,4,6,8,10,12,14
  • NUMA node1 CPU(s):1,3,5,7,9,11,13,15
  • Ram:48 gb
  • 操作系统:CentOS 7
  • 内核版本:Linux版本3.10.0-123.el7.x86_64(builder@kbuilder.dev.centos.org)(gcc版本4.8.2 20140120(Red Hat 4.8.2-16)(GCC))

我正在使用的流程详情:

使用以下命令编译Sqlite3

./configure --prefix=/usr --disable-static CFLAGS="-O3 -m64 -DSQLITE_DEFAULT_SYNCHRONOUS=0 -DSQLITE_CONFIG_SINGLETHREAD -DSQLITE_DEFAULT_AUTOMATIC_INDEX=0 -DSQLITE_DEFAULT_PAGE_SIZE=4096 -DSQLITE_DEFAULT_CACHE_SIZE=4000 -DHAVE_FDATASYNC=0"

创建表格查询:

create table 'Stream0' ( TokenNo int NOT NULL,OrderId integer NOT NULL,SIDE int NOT NULL,PRICE int NOT NULL,QTY int NOT NULL,PRIMARY KEY (OrderId));

表上的索引:

CREATE INDEX DataFilterIndex ON 'Stream0'(TokenNo , SIDE, Price,Qty);

Pragma声明:

void SqliteManager::SetPragma()
{
   rc= sqlite3_exec(db, "PRAGMA synchronous = OFF", NULL, NULL, &zErrMsg);
   rc= sqlite3_exec(db, "PRAGMA count_changes = false", NULL, NULL, &zErrMsg);
   rc= sqlite3_exec(db, "PRAGMA journal_mode = OFF", NULL, NULL, &zErrMsg);
}

准备Sqlite查询:

MyString <<"insert or replace into 'Stream0' values( ?1,?2,?3,?4,?5);";
rc= sqlite3_prepare_v2(db,MyString.str().c_str(),strlen(MyString.str().c_str()),&insert_stmt,NULL); 

注意: - 已使用插入或替换,因为任何指定TokenNo的传入数据可能带有修改标记,而在此之前没有任何插入标记。

MyString.str(std::string());
MyString <<"delete from 'Stream0' where OrderId = ?1;";
rc = sqlite3_prepare_v2(db,MyString.str().c_str(),strlen(MyString.str().c_str()),&delete_stmt,NULL);

一旦要求特定TokenNo的数据删除/插入/修改,就会引发select语句以向用户发布数据。

选择声明:

MyString<<"select TokenNo,Price ,sum(QTY) from 'Stream0' where TokenNo=?1 and Side=66 group by Price order by Price desc limit 5";
rc = sqlite3_prepare_v2(db,MyString.str().c_str(),strlen(MyString.str().c_str()),&select_bid_stmt,NULL);

这里Side = 66代表买家价格,而价格desc表示价格按降序排列。

还有一个是Side = 83代表卖家和价格Asc说价格按升序排序

如果为令牌添加插入/修改数据,则会根据收到的数据包中收到的Side,以Side = 66或Side = 83引发其中一个查询。

如果收到删除数据包,则必须背靠背释放两个查询。

如果我使用Insert / Replace / delete运行我的可执行文件,那么一切顺利就是:没有数据包丢失,但是当我开始使用Select查询时,在插入/替换后单独执行,或者在删除后,两者都开始使用。

我希望我能够描述我的整个情况。运行Select查询对我来说是必须的。请帮忙。

1 个答案:

答案 0 :(得分:0)

似乎你正在大量监听传入的数据包,但你查询例程的速度还不够快。    您正在使用功能强大的Xeon E5处理器,能够执行重型多线程,但您已在单线程模式下配置了sqlite3。尝试以多线程模式打开数据库。最好将数据包侦听器保留在一个线程中,以便主GUI线程保持响应。工作线程可以轻松执行插入/删除/查询数据库例程。