- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我们有一个应用程序通过 psqlodbc 09.00.0200 驱动程序以下列方式从 PostgreSQL 9.0.3 数据库获取一些数据:
1) SQLExecDirect with START TRANSACTION
2) SQLExecDirect 与
DECLARE foo SCROLL CURSOR FOR
SELECT table.alotofcolumns
FROM table
ORDER BY name2, id LIMIT 10000
3) SQLPrepare with
SELECT table.alotofcolumns, l01.languagedescription
FROM fetchcur('foo', ?, ?) table (column definitions)
LEFT OUTER JOIN languagetable l01 ON (l01.lang = 'EN'
AND l01.type = 'some type'
AND l01.grp = 'some group'
AND l01.key = table.somecolumn)
[~20 more LEFT OUTER JOINS in the same style, but for an other column]
4) SQLExecute,param1 设置为 SQL_FETCH_RELATIVE,param2 设置为 1
5) SQLExecute param1 设置为 SQL_FETCH_RELATIVE param2 设置为 -1
6) SQLExecute param1 设置为 SQL_FETCH_RELATIVE param2 设置为 0
7) 全部释放,关闭游标,结束事务
函数 fetchcur 执行 FETCH RELATIVE $3 IN $1 INTO rec
,其中 rec 是一条记录并返回该记录。步骤 4-6 根据用户请求一次又一次地执行,同时在此事务中执行了更多的查询。在发出另一个用户请求之前也可能需要相当长的时间。通常查询需要那么长时间:
4) ~ 130 毫秒
5) ~ 115 毫秒
6) ~ 110 毫秒
对于快速的用户体验来说,这通常太慢了。所以我在\timing on 的情况下从 psql 命令行尝试了相同的语句。对于第 3-6 步,我使用了该语句:
3)
PREPARE p_foo (INTEGER, INTEGER) AS
SELECT table.alotofcolumns, l01.languagedescription
FROM fetchcur('foo', $1, $2) table (column definitions)
LEFT OUTER JOIN languagetable l01 ON (l01.lang = 'EN'
AND l01.type = 'some type'
AND l01.grp = 'some group'
AND l01.key = table.somecolumn)
[~20 more LEFT OUTER JOINS in the same style, but for an other column]
4-6)
EXPLAIN ANALYZE EXECUTE p_foo (6, x);
对于第一个 EXECUTE,它花费了 89 毫秒,但随后下降到大约 7 毫秒。即使我在执行之间等待几分钟,每次查询也保持在 10 毫秒以下。那么额外的 100 毫秒会去哪里呢?应用程序和数据库在同一系统上,因此网络延迟应该不是问题。每个 LEFT OUTER JOIN 只返回一行,并且该结果中只有一列被添加到结果集中。所以结果是一行有 ~200 列,主要是 VARCHAR 和 INTEGER 类型。但是,在同一台机器上传输大约 100 毫秒的数据不应该如此之多。所以任何提示都会有所帮助。
机器有 2 GB 的 RAM,参数设置为:
shared_buffers = 512MB
effective_cache_size = 256MB
work_mem = 16MB
maintenance_work_mem = 256MB
temp_buffers = 8MB
wal_buffers= 1MB
编辑:我刚刚发现如何从 psqlodbc 创建一个 mylog,但我无法在其中找到计时值。
EDIT2:还可以为每一行添加时间戳。这确实表明在 psqlodbc 驱动程序收到响应之前需要 >100ms。所以我再次尝试使用 psql
并添加选项 -h 127.0.0.1
以确保它也通过 TCP/IP。 psql
的结果是 <10ms。这怎么可能?
00:07:51.026 [3086550720][SQLExecute]
00:07:51.026 [3086550720]PGAPI_Execute: entering...1
00:07:51.026 [3086550720]PGAPI_Execute: clear errors...
00:07:51.026 [3086550720]prepareParameters was not called, prepare state:3
00:07:51.026 [3086550720]SC_recycle_statement: self= 0x943b1e8
00:07:51.026 [3086550720]PDATA_free_params: ENTER, self=0x943b38c
00:07:51.026 [3086550720]PDATA_free_params: EXIT
00:07:51.026 [3086550720]Exec_with_parameters_resolved: copying statement params: trans_status=6, len=10128, stmt='SELECT [..]'
00:07:51.026 [3086550720]ResolveOneParam: from(fcType)=-15, to(fSqlType)=4(23)
00:07:51.026 [3086550720]cvt_null_date_string=0 pgtype=23 buf=(nil)
00:07:51.026 [3086550720]ResolveOneParam: from(fcType)=4, to(fSqlType)=4(23)
00:07:51.026 [3086550720]cvt_null_date_string=0 pgtype=23 buf=(nil)
00:07:51.026 [3086550720] stmt_with_params = 'SELECT [..]'
00:07:51.027 [3086550720]about to begin SC_execute
00:07:51.027 [3086550720] Sending SELECT statement on stmt=0x943b1e8, cursor_name='SQL_CUR0x943b1e8' qflag=0,1
00:07:51.027 [3086550720]CC_send_query: conn=0x9424668, query='SELECT [..]'
00:07:51.027 [3086550720]CC_send_query: conn=0x9424668, query='SAVEPOINT _EXEC_SVP_0x943b1e8'
00:07:51.027 [3086550720]send_query: done sending query 35bytes flushed
00:07:51.027 [3086550720]in QR_Constructor
00:07:51.027 [3086550720]exit QR_Constructor
00:07:51.027 [3086550720]read 21, global_socket_buffersize=4096
00:07:51.027 [3086550720]send_query: got id = 'C'
00:07:51.027 [3086550720]send_query: ok - 'C' - SAVEPOINT
00:07:51.027 [3086550720]send_query: setting cmdbuffer = 'SAVEPOINT'
00:07:51.027 [3086550720]send_query: returning res = 0x8781c90
00:07:51.027 [3086550720]send_query: got id = 'Z'
00:07:51.027 [3086550720]QResult: enter DESTRUCTOR
00:07:51.027 [3086550720]QResult: in QR_close_result
00:07:51.027 [3086550720]QResult: free memory in, fcount=0
00:07:51.027 [3086550720]QResult: free memory out
00:07:51.027 [3086550720]QResult: enter DESTRUCTOR
00:07:51.027 [3086550720]QResult: exit close_result
00:07:51.027 [3086550720]QResult: exit DESTRUCTOR
00:07:51.027 [3086550720]send_query: done sending query 1942bytes flushed
00:07:51.027 [3086550720]in QR_Constructor
00:07:51.027 [3086550720]exit QR_Constructor
00:07:51.027 [3086550720]read -1, global_socket_buffersize=4096
00:07:51.027 [3086550720]Lasterror=11
00:07:51.133 [3086550720]!!! poll ret=1 revents=1
00:07:51.133 [3086550720]read 4096, global_socket_buffersize=4096
00:07:51.133 [3086550720]send_query: got id = 'T'
00:07:51.133 [3086550720]QR_fetch_tuples: cursor = '', self->cursor=(nil)
00:07:51.133 [3086550720]num_fields = 166
00:07:51.133 [3086550720]READING ATTTYPMOD
00:07:51.133 [3086550720]CI_read_fields: fieldname='id', adtid=23, adtsize=4, atttypmod=-1 (rel,att)=(0,0)
[last two lines repeated for the other columns]
00:07:51.138 [3086550720]QR_fetch_tuples: past CI_read_fields: num_fields = 166
00:07:51.138 [3086550720]MALLOC: tuple_size = 100, size = 132800
00:07:51.138 [3086550720]QR_next_tuple: inTuples = true, falling through: fcount = 0, fetch_number = 0
00:07:51.139 [3086550720]qresult: len=3, buffer='282'
[last line repeated for the other columns]
00:07:51.140 [3086550720]end of tuple list -- setting inUse to false: this = 0x87807e8 SELECT 1
00:07:51.140 [3086550720]_QR_next_tuple: 'C' fetch_total = 1 & this_fetch = 1
00:07:51.140 [3086550720]QR_next_tuple: backend_rows < CACHE_SIZE: brows = 0, cache_size = 0
00:07:51.140 [3086550720]QR_next_tuple: reached eof now
00:07:51.140 [3086550720]send_query: got id = 'Z'
00:07:51.140 [3086550720] done sending the query:
00:07:51.140 [3086550720]extend_column_bindings: entering ... self=0x943b270, bindings_allocated=166, num_columns=166
00:07:51.140 [3086550720]exit extend_column_bindings=0x9469500
00:07:51.140 [3086550720]SC_set_Result(943b1e8, 87807e8)
00:07:51.140 [3086550720]QResult: enter DESTRUCTOR
00:07:51.140 [3086550720]retval=0
00:07:51.140 [3086550720]CC_send_query: conn=0x9424668, query='RELEASE _EXEC_SVP_0x943b1e8'
00:07:51.140 [3086550720]send_query: done sending query 33bytes flushed
00:07:51.140 [3086550720]in QR_Constructor
00:07:51.140 [3086550720]exit QR_Constructor
00:07:51.140 [3086550720]read -1, global_socket_buffersize=4096
00:07:51.140 [3086550720]Lasterror=11
00:07:51.140 [3086550720]!!! poll ret=1 revents=1
00:07:51.140 [3086550720]read 19, global_socket_buffersize=4096
00:07:51.140 [3086550720]send_query: got id = 'C'
00:07:51.140 [3086550720]send_query: ok - 'C' - RELEASE
00:07:51.140 [3086550720]send_query: setting cmdbuffer = 'RELEASE'
00:07:51.140 [3086550720]send_query: returning res = 0x877cd30
00:07:51.140 [3086550720]send_query: got id = 'Z'
00:07:51.140 [3086550720]QResult: enter DESTRUCTOR
00:07:51.140 [3086550720]QResult: in QR_close_result
00:07:51.140 [3086550720]QResult: free memory in, fcount=0
00:07:51.140 [3086550720]QResult: free memory out
00:07:51.140 [3086550720]QResult: enter DESTRUCTOR
00:07:51.140 [3086550720]QResult: exit close_result
00:07:51.140 [3086550720]QResult: exit DESTRUCTOR
EDIT3:我意识到我之前没有在 psql
测试中使用来自 mylog 的相同查询。 psqlodbc
似乎没有为 SQLPrepare 和 SQLExecute 使用 PREPARE
。它添加参数值并发送查询。正如 araqnid 所建议的,我将 log_duration
参数设置为 0,并将来自 postgresql 日志的结果与来自应用程序和 psql 的结果进行了比较。结果如下:
psql/app pglog
query executed from app: 110 ms 70 ms
psql with PREPARE/EXECUTE: 10 ms 5 ms
psql with full SELECT: 85 ms 70 ms
那么如何解释这些值呢?似乎大部分时间都花在将完整查询发送到数据库(10000 个字符)并生成执行计划上。如果那是真的,将对 SQLPrepare 和 SQLExecute 的调用更改为通过 SQLExecDirect 执行的显式 PREPARE/EXECUTE 语句可以解决问题。有异议吗?
最佳答案
我终于找到了问题所在,psqlodbc 的 SQLPrepare/SQLExecute 默认不执行 PREPARE/EXECUTE。驱动程序本身构建 SELECT 并发送它。
解决方案是将 UseServerSidePrepare=1
添加到 odbc.ini 或 SQLDriverConnect 的 ConnectionString。从应用程序测量的一个查询的总执行时间从 >100 毫秒下降到 5-10 毫秒。
关于sql - Postgres 通过 ODBC 查询慢了一个数量级?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5082789/
自己试试看: import pandas as pd s=pd.Series(xrange(5000000)) %timeit s.loc[[0]] # You need pandas 0.15.1
我最近开始使用 Delphi 中的 DataSnap 来生成 RESTful Web 服务。在遵循 Marco Cantu 本人和互联网上其他几个人的指导后,我成功地使整个“链条”正常工作。 但是有一
我一直在为操作系统类(class)编写以下代码,但结果有些奇怪。该代码创建x线程并同时运行它们,以便将两个平方矩阵相乘。每个线程将输入矩阵的Number_of_rows/Number_of_threa
我正在尝试确定何时使用 parallel包以加快运行某些分析所需的时间。我需要做的一件事是创建矩阵,比较具有不同行数的两个数据框中的变量。我在 StackOverflow 上问了一个关于有效方法的问题
我最近对我的代码进行了一些清理,并在此过程中更改了此内容(不完全是真实的代码): read = act readSTRef test1 term i var = do t v^!terms.
我正在计时查询和同一个查询的执行时间,分页。 foreach (var x in productSource.OrderBy(p => p.AdminDisplayName) .Wher
我正在开发一个项目 (WPF),我有一个 Datagrid 从数据库加载超过 5000 条记录,所以我使用 BackgroundWorker 来通知用户数据正在加载,但它太慢了,我需要等待将近 2分钟
我在查询中添加 ORDER BY 时遇到问题。没有 ORDER BY 查询大约需要 26ms,一旦我添加 ORDER BY,它大约需要 20s。 我尝试了几种不同的方法,但似乎可以减少时间。 尝试 F
我是 Android 开发新手,遇到了性能问题。当我的 GridView 有太多项目时,它会变得有点慢。有什么方法可以让它运行得更快一些吗? 这是我使用的代码: 适配器: public class C
这里的要点是: 1.设置query_cache_type = 0;重置查询缓存; 2.在 heidisql(或任何其他客户端 UI)中运行任何查询 --> 执行,例如 45 毫秒 3.使用以下代码运行
想象下表: CREATE TABLE drops( id BIGSERIAL PRIMARY KEY, loc VARCHAR(5) NOT NULL, tag INT NOT
我的表 test_table 中的示例数据: date symbol value created_time 2010-01-09 symbol1
首先,如果已经有人问过这个问题,我深表歉意,至少我找不到任何东西。 无论如何,我将每 5 分钟运行一次 cron 任务。该脚本加载 79 个外部页面,而每个页面包含大约 200 个我需要在数据库中检查
我有下面的 SQL 代码,它来自 MySQL 数据库。现在它给了我期望的结果,但是查询很慢,我想我应该在进一步之前加快这个查询的速度。 表agentstatusinformation有: PKEY(主
我需要获取一个对象在 Core Data 中数千个其他对象之间的排名。现在,这是我的代码: - (void)rankMethod { //Fetch all objects NSFet
我正在编写一个应用程序,我需要在其中读取用户的地址簿并显示他所有联系人的列表。我正在测试的 iPhone 有大约 100 个联系人,加载联系人确实需要很多时间。 ABAddressBookRef ad
我正在使用 javascript 将 160 行添加到包含 10 列的表格中。如果我这样做: var cellText = document.createTextNode(value); cell.a
我是 Swift 的新手,我已经设置了一个 tableView,它从 JSON 提要中提取数据并将其加载到表中。 表格加载正常,但是当表格中有超过 10 个单元格时,它会变得缓慢且有些滞后,特别是它到
我在 InitializeCulture 和 Page_PreInit 事件之间的 asp.net 页面中遇到性能问题。当我重写 DeterminePostBackMode() 时,我发现问题出在 b
我在 Hetzner 上有一个带有 256GB RAM 6 个 CPU(12 个线程) 的专用服务器,它位于德国。我有 CENTOS 7.5。 EA4。 我的问题是 SSL。每天大约 2 小时,我们在
我是一名优秀的程序员,十分优秀!