【发布时间】:2016-09-12 01:22:45
【问题描述】:
我遇到了一个与慢速 sqlite3 选择相关的问题。我在这个论坛上搜索了很多,并应用了许多在某处帮助我前进的建议。我认为我尝试使用 sqlite 的方式存在一些错误,或者可能是我在编译它时使用的设置。
在阅读了很多关于它的性能之后,我决定在 c++ 中使用 sqlite3。由于数据流入量很大,并且服务器在交换时设置在同地,如果由于任何原因导致数据包处理延迟,则可能会出现丢包,延迟的数据包在高频中没有用 交易环境。可以有 5 mbps 的最小数据包流,其中每个数据包的最大大小为 45 字节。我的 sqlite 设置为 In Memory 使用。
要了解我的完整问题,请查看以下详细信息。
以下是服务器的详细信息:
我尝试使用 Sqlite3 的服务器详细信息
- 架构:x86_64
- CPU 操作模式:32 位、64 位
- 字节顺序:小尾数
- CPU:16
- 在线 CPU 列表:0-15
- 每个内核的线程数:2
- 每个插槽的核心数:4
- 套接字:2 个
- NUMA 节点:2 个
- 供应商 ID:正版英特尔
- CPU 系列:6
- 型号:45
- 型号名称:Intel(R) Xeon(R) CPU E5-2643 0 @ 3.30GHz
- 步进:7
- CPU 频率:3400.160
- BogoMIPS:6603.86
- 虚拟化:VT-x
- L1d 缓存:32K
- L1i 缓存:32K
- 二级缓存:256K
- 三级缓存:10240K
- NUMA node0 CPU:0,2,4,6,8,10,12,14
- NUMA node1 CPU:1,3,5,7,9,11,13,15
- 内存: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 的任一数据删除/插入/修改,就会引发选择语句以将数据发布给用户。
选择语句:
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 代表买家的价格,Price desc 表示按降序排列的价格。
还有一个 Side = 83 代表卖方,Price Asc 表示价格以升序方式排序
如果插入/修改数据来自令牌,则根据传入数据包中接收到的一侧,使用 Side = 66 或 Side = 83 引发查询之一。
如果收到删除数据包,则必须背靠背释放两个查询。
如果我使用 Insert/Replace/delete 运行我的可执行文件,一切都很顺利,即:没有丢包,但是当我开始使用 Select 查询时,无论是在 Insert/Replace 之后单独使用还是在 Delete 之后同时使用,都会开始丢包。
我希望我能够描述我的整个情况。运行选择查询对我来说是必须的。请帮忙。
【问题讨论】: