【问题标题】:Slow Sqlite3 Select Query while Insert/Update/Delete has no issue插入/更新/删除时缓慢的 Sqlite3 选择查询没有问题
【发布时间】: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 之后同时使用,都会开始丢包。

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

【问题讨论】:

    标签: c++ linux sqlite


    【解决方案1】:

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

    【讨论】:

    • 对不起,我犯了一个错误。共有 5 个独立的流。他们每个人都在单独的线程上运行。我上面提到的是第一流。我得到了您的建议:我应该在一个线程上运行插入/更新/删除并在另一个线程上选择吗?
    • 单独线程作为监听器,没关系。如果您在 MT 模式下使用 sqlite3,您可以允许工作线程分别处理每个插入/更新/查询,这样您就不会丢失传入的数据。为此,在每种方法中以 MT 模式打开数据库,否则它将像您的情况一样被阻止。
    • 我接受了你的建议,然后在 sqlite3 中对 MT 进行了更多研究,在那里我发现了一个 link,上面写着“当你执行写操作时,SQLite 有一个非常保守的线程模型”,还有一个 @来自 sqlite 页面的 987654322@ 说“多线程:在这种模式下,只要没有在两个或多个线程中同时使用单个数据库连接,SQLite 可以被多个线程安全地使用。”
    • 所以我有点困惑,如果一个连接不能被多个线程使用,那么我将如何从不同的线程调用 select 语句。现在我的编译时语句是 ./configure - -prefix=/usr --disable-static CFLAGS="-O3 -m64 -DSQLITE_DEFAULT_SYNCHRONOUS=0 -DSQLITE_THREADSAFE=1 -DSQLITE_DEFAULT_AUTOMATIC_INDEX=0 -DSQLITE_DEFAULT_PAGE_SIZE=4096 -DSQLITE_DEFAULT_CACHE_SIZE=4000 -DHAVE_FDATASYNC=0"有样品吗?
    • 看到你有 5 个流,你有 5 个监听线程。这些线程会将数据插入到您的表中。为了进一步加快处理速度,您可以允许 addl 工作线程执行插入、更新、查询。但是要确保这些新的 addl 工作线程同时协同工作,您必须确保在其他线程中没有同时使用单个数据库连接。这可以通过打开表的新实例而不共享其他实例来实现。 void Insert(Data data,table_t table) { //MT模式开表 //关闭表 }
    猜你喜欢
    • 2018-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    相关资源
    最近更新 更多