PostgreSQL发送大型XML值太慢。

huangapple go评论59阅读模式
英文:

PostgreSQL sending large XML values is too slow

问题

以下是翻译好的部分:

我们有一张大约有1万行的表,具有以下结构:

  1. item_id:文本(主键)
  2. xml_1:XML
  3. xml_2:XML
  4. country:文本

运行以下查询需要大约9到10秒:

SELECT * FROM info_table
WHERE item_id IN ('item1', 'item2', ... -> 'item2000')

我们的每个SELECT查询都由大约2,000个左右的项目ID(字符串)数组组成,查询非常简单,我们正在寻求优化它(如果可能)。
每行的XML大小约为100KB

如果有帮助的话,我们的查询是在使用Knex的Node.JS中进行的,如下所示:

client.select('*').from('info_table').where('item_id', 'in', ids)

服务器使用由GCP Cloud SQL托管的PostgreSQL 14,具有2vCPU、8GB内存和100GB SSD

EXPLAIN(ANALYZE、BUFFERS)的结果如下:

Seq Scan on epg_test  (cost=4.85..740.17 rows=1939 width=601) (actual time=0.168..3.432 rows=1837 loops=1)
  Filter: (epg_id = ANY (Array of 2000 IDs)
  Rows Removed by Filter: 6051
  Buffers: shared hit=617
Planning:
  Buffers: shared hit=130
Planning Time: 1.999 ms
Execution Time: 3.590 ms

有什么建议吗?

英文:

We have a table with around 10k rows, with the following scheme:

  1. item_id: TEXT (Primary Key)
  2. xml_1: XML
  3. xml_2: XML
  4. country: TEXT

Running the following query takes around 9 to 10 seconds:

SELECT * FROM info_table
WHERE item_id IN ('item1','item2','...' -> 'item2000')

Each of our SELECT query is composed of an array of around 2,000+- of items ids (Strings), the query is extremely simple and we are looking to optimize it (if possible).
The size of the XML of each row is around 100Kb

If it helps our query is being done in Node.JS using Knex, such as:

client.select('*').from('info_table').where('item_id','in',ids)

The server is using PostgreSQL 14 hosted by GCP Cloud SQL with 2vCPU, 8GB Memory and 100GB SSD

Results of EXPLAIN (ANALYZE, BUFFERS):

Seq Scan on epg_test  (cost=4.85..740.17 rows=1939 width=601) (actual time=0.168..3.432 rows=1837 loops=1)
  Filter: (epg_id = ANY (Array of 2000 IDs)
  Rows Removed by Filter: 6051
  Buffers: shared hit=617
Planning:
  Buffers: shared hit=130
Planning Time: 1.999 ms
Execution Time: 3.590 ms

Any ideas of what we can do?

答案1

得分: 1

从你的问题和评论中可以清楚地看出,你的查询在PostgreSQL中的复杂度很低,只需要不到4毫秒。因此,索引或其他SQL调优不是解决方案的一部分。

显然,你正在返回一个大型结果集,大约有0.2 GiB左右。而且,你大约在十秒左右完成。这意味着你的吞吐量是20 MiB/秒,这是非常优秀的。特别是如果你是从GCP的某个位置的服务器检索数据到你所在地的机器上的话。(请记住,20兆字节每秒相当于每秒超过160兆比特。这是从一台机器推送到另一台机器的相当大的带宽。)

你如何让这个大数据传输更快地完成呢?

  1. 更多带宽。你需要和运维人员讨论这个问题。或者将运行查询的机器移动到与数据库机器更接近的网络位置。

  2. 在传输过程中对数据进行压缩。XML通常是可以被压缩的(从信息论的角度来看,它几乎是病态的冗长)。Node.js的PostgreSQL驱动程序(以及knex)有一个已经废弃的sslcompression连接字符串标志,它会对客户端和服务器之间的网络流量应用无损压缩。这可能会有所帮助。

    或者,你可以尝试通过已设置了 -C -- 压缩协议 -- 标志的ssh会话隧道传输数据库连接。

  3. 在数据库中对数据进行压缩。如果你这样做,请确保将压缩后的XML存储在具有二进制数据类型的列中。

总的来说,用十秒的时间处理这么多数据似乎并不是特别不合理。

英文:

From your question and comments, it's clear that the PostgreSQL complexity of your query is minimal. It takes under 4ms. Therefore, indexing or other SQL tuning isn't part of your solution.

It's also clear that you're returning a large result set, amounting to something like 0.2GiB. And, you're doing it in ten seconds or so. That means your throughput is 20MiB/sec which is excellent. This is especially true if you're retrieving it into a machine on your premises from a server located somewhere in GCP. (Keep in mind that 20megaBYTES a second takes upwards of 160megaBITS per second. That's a significant amount of bandwidth to push from one machine to another.)

How can you get this big data transfer to complete faster?

  1. More bandwidth. That you have to take up with your operations people. Or by moving the machine running the query closer on the net to the database machine.

  2. Compressing the data in transit. XML is generally quite compressible (information-theoretically it's almost pathologically verbose). The PostgreSQL driver for nodejs (and knex) has a deprecated sslcompression connection-string flag that will apply lossless compression to the client-server network traffic. That might help.

    Or, you may be able to tunnel your database connection through an ssh session set up with the -C -- compressed protocol -- flag.

  3. Compressing the data at rest in your database. If you do this make sure you store the compressed xml in columns with a binary data type.

All that being said, ten seconds to process that much data doesn't seem terribly unreasonable.

答案2

得分: 0

谢谢大家的反馈,这非常有帮助。

通过在将数据插入我们的PostgreSQL之前压缩XML数据,我们成功将查询时间缩短到2秒,从而大幅减小了数据大小。

我们使用了"zlib"和GZIP来压缩XML。

英文:

Thank you everyone for the input, it was very helpful.

We managed to get the query down to 2 seconds by compressing the XML data before inserting to our PostgreSQL resulting in a massive reduction in size generally.

We compressed the XML using "zlib" and GZIP.

huangapple
  • 本文由 发表于 2023年5月18日 01:00:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76274528.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定