我的表有四列,它们的数据类型为text,JSON,boolean和timestamp,我遇到了麻烦。我有一张桌子;
CREATE TABLE zamazin
(
paramuser_id text,
paramperson_id integer,
paramdata json,
paramisdeleted boolean,
paramactiontime timestamp without time zone
)
paramdata行大小为110KB及以上。
当我执行类似的查询时;
select * from zamazin
需要600秒。但是当分析查询时;
"Seq Scan on public.zamazin (cost=0.00..21.77 rows=1077 width=49) (actual time=0.008..0.151 rows=1077 loops=1)"
" Output: paramuser_id, paramperson_id, paramdata, paramisdeleted, paramactiontime"
" Buffers: shared hit=11"
"Planning time: 0.032 ms"
"Execution time: 0.236 ms"
为什么查询需要很长时间,我不明白。我认为这与TOAST结构有关。我也有1K行,但我的json列大小约为110KB,甚至可能超过它。
[当我调查为什么这些执行时间如此不同时,我发现了像TOAST这样的新存储逻辑。我忽略了有关TOAST逻辑的一些细节,并增加了一些配置,例如shared_buffers,work_mem,maintenance_work_mem,max_file_per_process。
但是我的查询没有性能改善。
我不明白为什么会这样。我的表大小为168 MB,但与该表相关的TOAST表大小为123 MB。
我的环境是;
PostgreSQL 9.4.1
Windows Server 2012 R2
16 GB RAM
100 GB HardDisk (Not SSD) – I also test SSD hard disk but there is no change in my execution time.
My database size 20 GB.
我的服务器配置;
Shared_buffers: 8GB
( If I understand correctly, PostgreSQL say, For 9.4 The useful range for shared_buffers on Windows systems is generally from 64MB to 512MB. Link: https://www.postgresql.org/docs/9.4/runtime-config-resource.html )
work_mem : 512 MB
maintenance_work_mem: 1GB
max_file_per_process: 10000
effective_cache_size: 8GB
我测试了许多客户端,例如psql,pgadmin3,pgadmin4和dbeaver,但是我的执行时间没有增加。
如何获得良好的性能?
我的前端代码就像;
/* it is a pseudocode*/
public static List<User> GetUsers()
{
User user;
List<User> users = new List<User>();
string errMsg = string.Empty;
string sql = string.Empty;
sql = @"select * from zamazin order by paramuser_id asc;";
}
try
{
Stopwatch sw = new Stopwatch();
sw.Start();
DataTable dt = DBHelper.DataTable(sql, null);
sw.Stop();
if (sw.ElapsedMilliseconds > 1500)
Debug.WriteLine("Finished " + sw.Elapsed.TotalMilliseconds + " ms");
if (dt == null)
throw new Exception();
sw.Restart();
foreach (DataRow rows in dt.Rows)
{
try
{
user = JsonConvert.DeserializeObject<User>(Convert.ToString(rows["data"]),
DL_General.Jsonsettings);
if (user != null)
{
users.Add(user);
}
}
catch (Exception ex)
{
///bla bla
}
}
sw.Stop();
if (sw.ElapsedMilliseconds > 1500)
Console.WriteLine(End loop " + sw.Elapsed.TotalMilliseconds + ");
return users;
}
catch (Exception e)
{
//bla bla
}
return new List<User>();
}
如果在服务器上确定查询执行时间,那么问题必然出在网络或客户机上,它们需要很长时间来呈现数据。