Uma Iyer
IBM Lenexa Lab
2004 年 1 月 本文描述 Informix Dynamic Server (IDS) 中的 SQL 语句缓存 (SQL Statement Cache, SSC) 功能。根据应用程序的类型,SQL 语句缓存这一功能有助于提高查询的性能。
简介
本文描述 Informix Dynamic Server (IDS) 中的 SQL 语句缓存 (SQL Statement Cache, SSC) 功能。SSC 是共享内存中的一块区域,用于存储和共享各用户会话间相同语句的数据结构。下面是使用 SSC 功能所带来的好处:
- 减少了内存消耗,因为查询数据结构是在不同用户间共享的。
- 查询处理时间更快,因为对存在于缓存中的语句,数据库服务器可以跳过解析和优化阶段,从而可以为查询提供更好的响应。
如果 SSC 功能已启用,数据库服务器会做以下事情:
- 当某个用户 user1发出一条 SQL 语句时,数据库服务器检查语句缓存,查看缓存中是否存在相同的语句。
- 如果缓存中不存在这样的语句,数据库服务器将解析、优化并执行该语句。它还将检查该语句是否适于输入到缓存中。如果该语句可以输入到缓存中,那么数据库服务器将为该语句在缓存中添加一个条目。
- 当用户 user2执行同样的语句时,数据库服务器将检查缓存并且在缓存中找到这条语句。因此它不会再次解析和优化该语句,而只是使用缓存中的信息执行该语句。
一条语句要想输入到缓存中,应满足一组条件。以下是这些条件中的一部分:
- 该语句应该是 SELECT、UPDATE、DELETE 和 INSERT 这四种语句之一。
- 该语句不应包含任何用户定义例程。
- 该语句不能包含任何 Temporary 或 Remote 表。
- 该语句不应包含子查询。
要了解一组详尽的条件,请参考 IBM Informix Guide to SQL: Syntax。
SSC 配置参数
对于每个应用程序,都可以使用一组参数对 SQL 语句缓存进行配置。这些参数还用于决定哪些语句应该输入到缓存中。我们将简要地考察一下每个参数。
- STMT_CACHE_HITS —— 这个参数用于指定一条查询在数据库服务器为其在缓存中设立完全缓存条目之前应该执行过的次数。如果查询执行过的次数少于这个值,那么服务器将在缓存中为这条语句设立一个 key-only 条目,这种条目只包含该语句的文本。以后该语句每执行一次, hits列的数字就加 1。当该语句执行过的次数达到这个参数的值时,数据库服务器将为其在缓存中设立一个完全缓存条目,这种条目包含语句和查询数据结构。
- STMT_CACHE_SIZE —— 这个变量用于指定语句缓存的大小。SSC 大小的默认值是 512 千字节。在下一节,我们将讨论配置这个参数时要考虑的一些事情。
- STMT_CACHE_NOLIMIT —— 这个变量用于指定是否将缓存的大小限制为 STMT_CACHE_SIZE 值。默认情况下,即使缓存的大小超过了 STMT_CACHE_SIZE 值,服务器也会将语句输入到缓存中。
- STMT_CACHE_NUMPOOL —— 当服务器需要在语句缓存中创建一个完全缓存条目时,默认情况下它会只从单个池中分配内存。当应用程序的用户数量非常大时,这会对性能产生负面影响。在这种情况下,可以使用这个参数将池的数量配置得更大一些。
使用 onstat实用程序监视 SSC 的使用情况
onstat -g ssc选项显示语句缓存中的完全缓存条目。输出中的 hits列表明同一条语句执行过的次数。因此, hits 列中的值较大就意味着我们更有效地使用了 SQL 语句缓存来共享查询结构,从而也就提高了性能。 #hits 列与 STMT_CACHE_HITS 配置参数相对应。
输出中的 flag(标志)列表明该条目是否是完全缓存的。当一条语句执行过的次数达到 #hits 值的时候,数据库服务器就会在缓存中为其设立一个完全缓存条目。flag 列中的 F值表明该条目是完全缓存的。key-only 条目(只在缓存中输入了语句的文本)是通过 flag 列中的 - 来表明的。不过,只有在 onstat -g sscall 输出中才有这些条目。
图 1: 使用 onstat -g ssc 监视完全缓存条目
IBM Informix Dynamic Server Version 9.40.UC1 -- On-Line -- Up 04:34:47
-- 32768 Kbytes
Statement Cache Summary:
#lrus currsize maxsize Poolsize #hits nolimit
4 551936 30720000 278528 3 1
Statement Cache Entries:
lru hash ref_cnt hits flag heap_ptr database user
-----------------------------------------------------------------
3 235 0 3 -F b8b0820 test uiyer
select count(*) from tab2, tab1
where tab1.htl_key = tab2.htl_key AND tab1.doa = tab2.dt
Total number of entries: 1.
|
onstat -g ssc all命令同时显示 key-only 条目和完全缓存条目。
图 2: 使用 onstat -g ssc all 监视所有 SSC 条目
IBM Informix Dynamic Server Version 9.40.UC1 -- On-Line -- Up
00:19:17 -- 32768 Kbytes
Statement Cache Summary:
#lrus currsize maxsize Poolsize #hits nolimit
4 547840 30720000 270336 3 1
Statement Cache Entries:
lru hash ref_cnt hits flag heap_ptr database user
-------------------------------------------------------------------
0 16 0 0 -- b645690 sysmaster informix
insert into flags_text values ('systwaits', 0, 'unspecified')
0 18 0 0 -- b92d820 sysmaster informix
insert into flags_text values ('systwaits', 4, 'mt yield 0')
insert into flags_text values ('sqltype', 46, 'SQ_WAITFOR')
...
3 135 0 1 -- b8b2020 test uiyer
select count(*) from informix.systables where tabname = 'sysindices';
3 286 0 0 -- b8b2c20 test uiyer
insert into tab2 values (1, '10102003')
3 235 0 3 -F b8b0820 test uiyer
select count(*) from tab2, tab1
where tab1.htl_key = tab2.htl_key AND tab1.doa = tab2.dt
Total number of entries: 256.
|
使用 onmode实用程序配置 SSC 参数
配置参数可以通过使用 onmode实用程序动态地进行更改。
可以使用 onmode -W选项来更改 SSC 参数的值,用法如下:
onmode -W {STMT_CACHE_NOLIMIT {0|1} | STMT_CACHE_HITS <#hits>}
也可以使用 onmode -e <mode> 实用程序来启用、打开/关闭或清除 SSC,其中 <mode> := {ENABLE|ON|OFF|FLUSH}。
如果 SSC 模式设为 ENABLE,那么只有显式地请求使用 SSC 的各个会话才会使用 SSC。这使得那些很少执行特定查询的应用程序可以利用 SSC 的优点,而不让大量来自其他应用程序的特定查询浪费空间或者迫使缓存的语句从 SSC 中移出。会话通过 SSC 的环境(STMT_CACHE=1)或者通过执行 SET STATEMENT CACHE ON 来请求对 SSC 的使用。
当 SSC 被刷新时,正在使用的语句将被打上标记,在它们被释放之后再进行刷新。当 SSC 被关闭时,它将立即禁用共享。仍在使用 SSC 的语句将继续使用其共享版本,直到这些语句被释放为止。
调整 SSC 配置参数以提高性能
语句缓存的大小对数据库服务器性能的提高有着很重要的影响。 onstat -g ssc输出在 maxsize 列中显示这个参数的值。下面是一些提示,我们可以使用这些提示来调整 SSC 的大小:
- 检查经常执行的语句是否在缓存中。如果不在,那么很可能是 SSC 太小了,迫使这些语句从 SSC 中移出,以便输入新的语句。这种情况下应尝试增加 SSC 的大小。
- 如果有大量查询要重复地执行,那么 SSC 很可能会被充满,这样的话服务器最后就要花大量的时间来清除缓存。为了接纳适合输入到缓存中的新查询,服务器将把那些最近最少使用的条目从缓存中清除。然而,有时候碰巧新语句要使用这些条目中的某一个,但最终该查询还是不得不再次进行解析和优化,从而导致处理时间更长。如果出现这种情况,那么增加 SSC 的大小会有所帮助,因为这样的话这些情况出现的机会就会减少。
另一个要根据应用程序的需要进行微调的配置参数是 STMT_CACHE_HITS 参数。在决定这个参数的值时,下面这些因素很有帮助:
- onstat -g ssc 输出显示缓存中的完全缓存条目。然而,如果经常使用的查询不在缓存中,那么一个可能的原因就是 hits 值的数字太高了。这意味着该语句在进入缓存之前所花的时间太长了。在这种情况下,应尝试减小 STMT_CACHE_HITS 值。
- 如果 hits 值的数字太小,那么最终服务器就可能把那些只执行过一次的条目输入到缓存中,这样将导致那些经常执行的查询被替换。这可以通过查看 onstat -g ssc all 输出来判断。如果存在很多这样的查询:其在缓存中的条目在 flag 列中具有 F 标志并且 #hits列刚好为 0,那么应该检查输出中的 hits 列的值。如果该列的值为 0,则表明这些语句没有被重复执行。这时应增加 STMT_CACHE_HITS 参数的值,以便只有那些执行过一定次数的语句才可以输入到缓存中。
- 一般说来, onstat -g ssc输出中 hits列的值较高就表明 SSC 被有效地用来共享查询结构。
语句缓存池
当服务器需要在语句缓存中创建一个完全缓存条目时,默认情况下它只从单个池中分配内存。如果使用应用程序的用户数量很多,那么这种默认做法就可能对性能产生负面影响。在这种情况下,使用 STMT_CACHE_NUMPOOL 变量可以将池的数量配置成一个较高的数字。
您可以使用 onstat -g ssc pool 命令来监视 SSC 池 (sscpool) 的数量和大小。下面的输出显示这里配置了两个 SSC 池。每个池的大小可以在 totalsize列下找到。
图 3: 使用 onstat -g ssc pool 监视 SSC 池的使用情况
IBM Informix Dynamic Server Version 9.40.UC1 -- On-Line -- Up 00:00:24
--32768 Kbytes
Pool Summary:
name class addr totalsize freesize #allocfrag #freefrag
sscpool0 V b645020 8192 2808 2 2
Blkpool Summary:
name class addr size #blks
Pool Summary:
name class addr totalsize freesize #allocfrag #freefrag
sscpool1 V b646020 8192 1424 6 2
Blkpool Summary:
name class addr size #blks
|
onstat -g spi命令可用来判断 SSC 池的数量是否需要增加。该命令的输出显示了一些资源,在获得这些资源的闩锁(latch)之前至少有一个请求者在等待。
图 4: 使用 onstat -g spi 来监视资源
IBM Informix Dynamic Server Version 9.40.UC1 -- On-Line -- Up 00:00:59
--32768 Kbytes
Spin locks with waits:
Num Waits Num Loops Avg Loop/Wait Name
1 1 1.00 mutex lock, name = AIOreq
1 6 6.00 shmcb sh_lock
|
Num Waits列表明线程为得到一个闩锁(锁的所有权)而必须等待的次数。 Num Loops列表明总共的等待时间,这是按照线程在得到一个闩锁之前需循环或自旋(spin)的次数来计算的。在上面的输出中, Name 列没有显示任何 SSC 池。这说明当前配置的值不需要更改。如果 Name列显示了一个 SSC 池条目,那么在 Num Loops列中较高的值就表明需要增加 SSC 池的数量。
结束语
取决于应用程序的类型,SQL 语句缓存功能可以帮助提高查询的性能。在使用大量特定查询的应用程序中,同一条查询执行不止一次的情况很少。在这种情况下,我们不推荐使用 SSC。而在应用程序使用大量准备好的语句(prepared statement)或同一条查询要执行多次的情况下,启用 SSC 功能对提高性能和更快得到结果非常有益。
关于作者
Uma Iyer 是 IBM Lenexa Lab 中 Informix Dynamic Server 的开发人员,同时也是 SQL 开发小组成员之一。可以通过 uiyer@us.ibm.com 与 Uma 联系。 |
|