数据库排序与程序化 Java 排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1883264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
database sort vs. programmatic java sort
提问by Moro
I want to get data from the database (MySQL) by JPA, I want it sorted by some column value.
我想通过 JPA 从数据库(MySQL)获取数据,我希望它按某个列值排序。
So, what is the best practice, to:
那么,最佳实践是什么:
- Retrieve the data from the database as list of objects (JPA), then sort it programmatically using some java APIs.
- 从数据库中检索数据作为对象列表 (JPA),然后使用一些 Java API 以编程方式对其进行排序。
OR
或者
- Let the database sort it by using a sorting select query.
- 让数据库使用排序选择查询对其进行排序。
Thanks in advance
提前致谢
采纳答案by Gennadiy
If you are retrieving a subset of all the database data, for example displaying 20 rows on screen out of 1000, it is better to sort on the database. This will be faster and easier and will allow you to retrieve one page of rows (20, 50, 100) at a time instead of all of them.
如果您要检索所有数据库数据的子集,例如在屏幕上显示 1000 行中的 20 行,则最好对数据库进行排序。这将更快更容易,并且允许您一次检索一页行(20、50、100)而不是所有行。
If your dataset is fairly small, sorting in your code may be more convenient if you want implement a complex sort. Usually this complex sort can be done in SQL
but not as easily as in code.
如果您的数据集相当小,并且想要实现复杂的排序,那么在代码中排序可能会更方便。通常这种复杂的排序可以SQL
在代码中完成,但不像在代码中那么容易。
The short of it is, the rule of thumb is sort via SQL
, with some edge cases to the rule.
简而言之,经验法则是通过排序SQL
,规则有一些边缘情况。
回答by Crowe T. Robot
I'm almost positive that it will be faster to allow the Database to sort it. There's engineers who spend a lot of time perfecting and optimizing their search algorithms, whereas you'll have to implement your own sorting algorithm which might add a few more computations.
我几乎肯定允许数据库对其进行排序会更快。有些工程师花费大量时间完善和优化他们的搜索算法,而您必须实现自己的排序算法,这可能会增加一些计算。
回答by Otávio Décio
I would let the database do the sort, they are generally very good at that.
我会让数据库做排序,他们通常非常擅长。
回答by Alex Martelli
In general, you're better off using ORDER BY
in your SQL query -- this way, if there is an applicable index, you may be getting your sorting "for free" (worst case, it will be the same amount of work as doing it in your code, but often it may be less work than that!).
一般来说,最好ORDER BY
在 SQL 查询中使用 - 这样,如果有适用的索引,您可能会“免费”进行排序(最坏的情况是,它的工作量与执行此操作的工作量相同在您的代码中,但通常它的工作量可能比这少!)。
回答by Phil Sandler
This is not completely on point, but I posted something recently that relates to database vs. application-side sorting. The article is about a .net technique, so most of it likely won't be interesting to you, but the basic principles remain:
这并不完全正确,但我最近发布了一些与数据库与应用程序端排序相关的内容。这篇文章是关于 .net 技术的,因此您可能不会对其中的大部分内容感兴趣,但基本原则仍然存在:
Deferring sorting to the client side (e.g. jQuery, Dataset/Dataview sorting) may look tempting. And it actually is a viable option for paging, sorting and filtering, if (and only if):
将排序推迟到客户端(例如 jQuery、Dataset/Dataview 排序)可能看起来很诱人。它实际上是分页、排序和过滤的可行选项,如果(且仅当):
1. the set of data is small, and
1.数据集小,并且
1. there is little concern about performance and scalability
1. 很少关心性能和可扩展性
From my experience, the systems that meet this kind of criteria are few and far between. Note that it's not possible to mix and match sorting/paging in the application/database—if you ask the database for an unsorted 100 rows of data, then sort those rows on the application side, you're likely not going to get the set of data you were expecting. This may seem obvious, but I've seen the mistake made enough times that I wanted to at least mention it.
根据我的经验,满足这种标准的系统很少见。请注意,在应用程序/数据库中混合和匹配排序/分页是不可能的——如果您要求数据库提供未排序的 100 行数据,然后在应用程序端对这些行进行排序,您可能不会得到集合您期望的数据。这似乎很明显,但我已经看到这个错误发生的次数太多了,我至少想提一下。
It is much more efficient to sort and filter in the database for a number of reasons. For one thing, database engines are highly optimized for doing exactly the kind of work that sorting and filtering entail; this is what their underlying code was designed to do. But even barring that—even assuming you could write code that could match the kind of sorting, filtering and paging performance of a mature database engine—it's still preferable to do this work in the database, for the simple reason that it's more efficient to limit the amount of data that is transferred from the database to the application server.
出于多种原因,在数据库中进行排序和过滤的效率要高得多。一方面,数据库引擎经过高度优化,可以完成排序和过滤所需的工作;这就是他们的底层代码的设计目的。但即便如此——即使假设您可以编写与成熟数据库引擎的排序、过滤和分页性能相匹配的代码——仍然最好在数据库中完成这项工作,原因很简单,限制更有效从数据库传输到应用程序服务器的数据量。
So for example, if you have 10,000 rows before filtering, and your query pares that number down to 75, filtering on the client results in the data from all 10,000 rows being passed over the wire (and into your app server's memory), where filtering on the database side would result in only the filtered 75 rows being moved between database and application. his can make a huge impact on performance and scalability.
因此,例如,如果您在过滤前有 10,000 行,并且您的查询将该数字缩减为 75,则在客户端上过滤会导致所有 10,000 行中的数据通过网络传递(并进入您的应用程序服务器的内存),其中过滤在数据库端将导致仅过滤的 75 行在数据库和应用程序之间移动。他可以对性能和可扩展性产生巨大影响。
The full post is here: http://psandler.wordpress.com/2009/11/20/dynamic-search-objects-part-5sorting/
完整的帖子在这里:http: //psandler.wordpress.com/2009/11/20/dynamic-search-objects-part-5sorting/
回答by Thorbj?rn Ravn Andersen
Let the database sort it. Then you can have paging with JPA easily without readin in the whole resultset.
让数据库对其进行排序。然后,您可以轻松地使用 JPA 进行分页,而无需读取整个结果集。
回答by Paul
I ran into this very same question, and decided that I should run a little benchmark to quantify the speed differences. The results surprised me. I would like to post my experience with this very sort of question.
我遇到了同样的问题,并决定我应该运行一个小基准来量化速度差异。结果令我吃惊。我想发表我对这类问题的经验。
As with a number of the other posters here, my thought was that the database layer would do the sort faster because they are supposedly tuned for this sort of thing. @Alex made a good point that if the database already has an index on the sort, then it will be faster. I wanted to answer the question which raw sorting is faster on non-indexed sorts. Note, I said faster, not simpler. I think in many cases letting the db do the work is simpler and less error prone.
与这里的许多其他海报一样,我的想法是数据库层会更快地进行排序,因为据说它们已针对此类事情进行了调整。@Alex 提出了一个很好的观点,如果数据库已经在排序上有一个索引,那么它会更快。我想回答在非索引排序中原始排序更快的问题。注意,我说的是更快,而不是更简单。我认为在许多情况下,让 db 来完成工作更简单,更不容易出错。
My main assumption was that the sort would fit in main memory. Not all problems will fit here, but a good number do. For out of memory sorts, it may well be that databases shine here, though I did not test that. In the case of in memory sorts all of java/c/c++ outperformed mysql in my informal benchmark, if one could call it that.
我的主要假设是这种排序适合主内存。并非所有问题都适合这里,但很多问题都适合。对于内存不足的排序,很可能是数据库在这里大放异彩,尽管我没有对此进行测试。在内存排序的情况下,所有 java/c/c++ 在我的非正式基准测试中都优于 mysql,如果可以这样称呼的话。
I wish I had had more time to more thoroughly compare the database layer vs application layer, but alas other duties called. Still, I couldn't help but record this note for others who are traveling down this road.
我希望我有更多的时间来更彻底地比较数据库层与应用程序层,但可惜的是其他职责。尽管如此,我还是忍不住为正在这条路上旅行的其他人记录了这个笔记。
As I started down this path I started to see more hurdles. Should I compare data transfer? How? Can I compare time to read db vs time to read a flat file in java? How to isolate the sort time vs data transfer time vs time to read the records? With these questions here was the methodology and timing numbers I came up with.
当我开始走这条路时,我开始看到更多的障碍。我应该比较数据传输吗?如何?我可以比较读取 db 的时间与读取 java 中的平面文件的时间吗?如何隔离排序时间与数据传输时间与读取记录的时间?带着这些问题,我想出了方法论和时间数字。
All times in ms unless otherwise posted
除非另有发布,所有时间均以毫秒为单位
All sort routines were the defaults provided by the language (these are good enough for random sorted data)
所有排序例程都是语言提供的默认值(这些对于随机排序的数据来说已经足够了)
All compilation was with a typical "release-profile" selected via netbeans with no customization unless otherwise posted
所有编译均使用通过 netbeans 选择的典型“发布配置文件”,除非另行发布,否则不进行自定义
All tests for mysql used the following schema
mysql 的所有测试都使用以下模式
mysql> CREATE TABLE test_1000000
(
pk bigint(11) NOT NULL,
float_value DOUBLE NULL,
bigint_value bigint(11) NULL,
PRIMARY KEY (pk )
) Engine MyISAM;
mysql> describe test_1000000;
+--------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------+------+-----+---------+-------+
| pk | bigint(11) | NO | PRI | NULL | |
| float_value | double | YES | | NULL | |
| bigint_value | bigint(11) | YES | | NULL | |
+--------------+------------+------+-----+---------+-------+
First here is a little snippet to populate the DB. There may be easier ways, but this is what I did:
首先这里是一个小片段来填充数据库。可能有更简单的方法,但这就是我所做的:
public static void BuildTable(Connection conn, String tableName, long iterations) {
Random ran = new Random();
Math.random();
try {
long epoch = System.currentTimeMillis();
for (long i = 0; i < iterations; i++) {
if (i % 100000 == 0) {
System.out.println(i + " next 100k");
}
PerformQuery(conn, tableName, i, ran.nextDouble(), ran.nextLong());
}
} catch (Exception e) {
logger.error("Caught General Exception Error from main " + e);
}
}
MYSQL Direct CLI results:
MYSQL 直接 CLI 结果:
select * from test_10000000 order by bigint_value limit 10;
10 rows in set (2.32 sec)
These timings were somewhat difficult as the only info I had was the time reported after the execution of the command.
这些时间安排有点困难,因为我唯一的信息是执行命令后报告的时间。
from mysql prompt for 10000000 elements it is roughly 2.1 to 2.4 either for sorting bigint_value or float_value
从 mysql 提示 10000000 个元素,它大约是 2.1 到 2.4,用于排序 bigint_value 或 float_value
Java JDBC mysql call (similar performance to doing sort from mysql cli)
Java JDBC mysql 调用(类似于从 mysql cli 进行排序的性能)
public static void SortDatabaseViaMysql(Connection conn, String tableName) {
try {
Statement stmt = conn.createStatement();
String cmd = "SELECT * FROM " + tableName + " order by float_value limit 100";
ResultSet rs = stmt.executeQuery(cmd);
} catch (Exception e) {
}
}
Five runs:
五次运行:
da=2379 ms
da=2361 ms
da=2443 ms
da=2453 ms
da=2362 ms
Java Sort Generating random numbers on fly (actually was slower than disk IO read). Assignment time is the time to generate random numbers and populate the array
Java Sort 动态生成随机数(实际上比磁盘 IO 读取慢)。分配时间是生成随机数并填充数组的时间
Calling like
像打电话一样
JavaSort(10,10000000);
Timing results:
计时结果:
assignment time 331 sort time 1139
assignment time 324 sort time 1037
assignment time 317 sort time 1028
assignment time 319 sort time 1026
assignment time 317 sort time 1018
assignment time 325 sort time 1025
assignment time 317 sort time 1024
assignment time 318 sort time 1054
assignment time 317 sort time 1024
assignment time 317 sort time 1017
These results were for reading a file of doubles in binary mode
这些结果用于以二进制模式读取双精度文件
assignment time 4661 sort time 1056
assignment time 4631 sort time 1024
assignment time 4733 sort time 1004
assignment time 4725 sort time 980
assignment time 4635 sort time 980
assignment time 4725 sort time 980
assignment time 4667 sort time 978
assignment time 4668 sort time 980
assignment time 4757 sort time 982
assignment time 4765 sort time 987
Doing a buffer transfer results in much faster runtimes
进行缓冲区传输会导致运行时间更快
assignment time 77 sort time 1192
assignment time 59 sort time 1125
assignment time 55 sort time 999
assignment time 55 sort time 1000
assignment time 56 sort time 999
assignment time 54 sort time 1010
assignment time 55 sort time 999
assignment time 56 sort time 1000
assignment time 55 sort time 1002
assignment time 56 sort time 1002
C and C++ Timing results (see below for source)
C 和 C++ 计时结果(源代码见下文)
Debug profile using qsort
使用 qsort 调试配置文件
assignment 0 seconds 110 milliseconds Time taken 2 seconds 340 milliseconds
assignment 0 seconds 90 milliseconds Time taken 2 seconds 340 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 330 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 340 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 330 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 340 milliseconds
assignment 0 seconds 90 milliseconds Time taken 2 seconds 340 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 330 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 340 milliseconds
assignment 0 seconds 100 milliseconds Time taken 2 seconds 330 milliseconds
Release profile using qsort
使用 qsort 发布配置文件
assignment 0 seconds 100 milliseconds Time taken 1 seconds 600 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 600 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 580 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 590 milliseconds
assignment 0 seconds 80 milliseconds Time taken 1 seconds 590 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 590 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 600 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 590 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 600 milliseconds
assignment 0 seconds 90 milliseconds Time taken 1 seconds 580 milliseconds
Release profile Using std::sort( a, a + ARRAY_SIZE );
发布配置文件使用 std::sort( a, a + ARRAY_SIZE );
assignment 0 seconds 100 milliseconds Time taken 0 seconds 880 milliseconds
assignment 0 seconds 90 milliseconds Time taken 0 seconds 870 milliseconds
assignment 0 seconds 90 milliseconds Time taken 0 seconds 890 milliseconds
assignment 0 seconds 120 milliseconds Time taken 0 seconds 890 milliseconds
assignment 0 seconds 90 milliseconds Time taken 0 seconds 890 milliseconds
assignment 0 seconds 90 milliseconds Time taken 0 seconds 880 milliseconds
assignment 0 seconds 90 milliseconds Time taken 0 seconds 900 milliseconds
assignment 0 seconds 90 milliseconds Time taken 0 seconds 890 milliseconds
assignment 0 seconds 100 milliseconds Time taken 0 seconds 890 milliseconds
assignment 0 seconds 150 milliseconds Time taken 0 seconds 870 milliseconds
Release profile Reading random data from file and using std::sort( a, a + ARRAY_SIZE )
发布配置文件从文件中读取随机数据并使用 std::sort( a, a + ARRAY_SIZE )
assignment 0 seconds 50 milliseconds Time taken 0 seconds 880 milliseconds
assignment 0 seconds 40 milliseconds Time taken 0 seconds 880 milliseconds
assignment 0 seconds 50 milliseconds Time taken 0 seconds 880 milliseconds
assignment 0 seconds 50 milliseconds Time taken 0 seconds 880 milliseconds
assignment 0 seconds 40 milliseconds Time taken 0 seconds 880 milliseconds
Below is the source code used. Hopefully minimal bugs :)
下面是使用的源代码。希望最小的错误:)
Java source Note that internal to JavaSort the runCode and writeFlag need to be adjusted depending on what you want to time. Also note that the memory allocation happens in the for loop (thus testing GC, but I did not see any appreciable difference moving the allocation outside the loop)
Java 源 请注意,JavaSort 内部的 runCode 和 writeFlag 需要根据您想要的时间进行调整。另请注意,内存分配发生在 for 循环中(因此测试了 GC,但我没有看到将分配移到循环外的任何明显差异)
public static void JavaSort(int iterations, int numberElements) {
Random ran = new Random();
Math.random();
int runCode = 2;
boolean writeFlag = false;
for (int j = 0; j < iterations; j++) {
double[] a1 = new double[numberElements];
long timea = System.currentTimeMillis();
if (runCode == 0) {
for (int i = 0; i < numberElements; i++) {
a1[i] = ran.nextDouble();
}
}
else if (runCode == 1) {
//do disk io!!
try {
DataInputStream in = new DataInputStream(new FileInputStream("MyBinaryFile.txt"));
int i = 0;
//while (in.available() > 0) {
while (i < numberElements) { //this should be changed so that I always read in the size of array elements
a1[i++] = in.readDouble();
}
}
catch (Exception e) {
}
}
else if (runCode == 2) {
try {
FileInputStream stream = new FileInputStream("MyBinaryFile.txt");
FileChannel inChannel = stream.getChannel();
ByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
//int[] result = new int[500000];
buffer.order(ByteOrder.BIG_ENDIAN);
DoubleBuffer doubleBuffer = buffer.asDoubleBuffer();
doubleBuffer.get(a1);
}
catch (Exception e) {
}
}
if (writeFlag) {
try {
DataOutputStream out = new DataOutputStream(new FileOutputStream("MyBinaryFile.txt"));
for (int i = 0; i < numberElements; i++) {
out.writeDouble(a1[i]);
}
} catch (Exception e) {
}
}
long timeb = System.currentTimeMillis();
Arrays.sort(a1);
long timec = System.currentTimeMillis();
System.out.println("assignment time " + (timeb - timea) + " " + " sort time " + (timec - timeb));
//delete a1;
}
}
C/C++ source
C/C++ 源代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define ARRAY_SIZE 10000000
using namespace std;
int compa(const void * elem1, const void * elem2) {
double f = *((double*) elem1);
double s = *((double*) elem2);
if (f > s) return 1;
if (f < s) return -1;
return 0;
}
int compb (const void *a, const void *b) {
if (*(double **)a < *(double **)b) return -1;
if (*(double **)a > *(double **)b) return 1;
return 0;
}
void timing_testa(int iterations) {
clock_t start = clock(), diffa, diffb;
int msec;
bool writeFlag = false;
int runCode = 1;
for (int loopCounter = 0; loopCounter < iterations; loopCounter++) {
double *a = (double *) malloc(sizeof (double)*ARRAY_SIZE);
start = clock();
size_t bytes = sizeof (double)*ARRAY_SIZE;
if (runCode == 0) {
for (int i = 0; i < ARRAY_SIZE; i++) {
a[i] = rand() / (RAND_MAX + 1.0);
}
}
else if (runCode == 1) {
ifstream inlezen;
inlezen.open("test", ios::in | ios::binary);
inlezen.read(reinterpret_cast<char*> (&a[0]), bytes);
}
if (writeFlag) {
ofstream outf;
const char* pointer = reinterpret_cast<const char*>(&a[0]);
outf.open("test", ios::out | ios::binary);
outf.write(pointer, bytes);
outf.close();
}
diffa = clock() - start;
msec = diffa * 1000 / CLOCKS_PER_SEC;
printf("assignment %d seconds %d milliseconds\t", msec / 1000, msec % 1000);
start = clock();
//qsort(a, ARRAY_SIZE, sizeof (double), compa);
std::sort( a, a + ARRAY_SIZE );
//printf("%f %f %f\n",a[0],a[1000],a[ARRAY_SIZE-1]);
diffb = clock() - start;
msec = diffb * 1000 / CLOCKS_PER_SEC;
printf("Time taken %d seconds %d milliseconds\n", msec / 1000, msec % 1000);
free(a);
}
}
/*
*
*/
int main(int argc, char** argv) {
printf("hello world\n");
double *a = (double *) malloc(sizeof (double)*ARRAY_SIZE);
//srand(1);//change seed to fix it
srand(time(NULL));
timing_testa(5);
free(a);
return 0;
}
回答by Kingz
Well, there is not really a straightforward way to answer this; it must be answered in the context.
嗯,没有一个真正直接的方法来回答这个问题。必须结合上下文来回答。
Is your application (middle tier) is running in the same node as the database?
您的应用程序(中间层)是否与数据库在同一节点中运行?
If yes, you do not have to worry about the latency between the database and middle tier. Then the question becomes: How big is the subset/resultset of your query? Remember that to sort this is middle tier, you will take a list/set of size N, and either write a custom comparator or use the default Collection comparator. Or, whatever. So at the outset, you are setback by the size N.
如果是,您不必担心数据库和中间层之间的延迟。那么问题就变成了:查询的子集/结果集有多大?请记住,要排序这是中间层,您将采用大小为 N 的列表/集,并编写自定义比较器或使用默认集合比较器。管他呢。所以一开始,你会被大小 N 所挫败。
But if the answer is no, then you are hit by the latency involved in transferring your resultset from DB to middle tier. And then if you are performing pagination, which is the last thing you should do, you are throwing away 90-95% of that resultset after cutting the pages.
但如果答案是否定的,那么您就会受到将结果集从数据库传输到中间层所涉及的延迟的影响。然后,如果您正在执行分页,这是您应该做的最后一件事,那么您将在剪切页面后丢弃 90-95% 的结果集。
So the wasted bandwidth cannot be justified. Imagine doing this for every request, across your tenant organizations.
所以浪费的带宽是不合理的。想象一下,跨租户组织为每个请求执行此操作。
However way you look at it, this is bad design.
不管你怎么看,这都是糟糕的设计。
I would do this in the database, no matter what. Just because almost all applications today demand pagination; even if they don't sending massive resultsets over the wire to your client is a total waste; drags everybody down across all your tenants.
无论如何,我都会在数据库中执行此操作。只是因为今天几乎所有的应用程序都需要分页;即使他们没有通过网络向您的客户发送大量结果集也是一种浪费;将每个人拖到所有租户中。
One interesting idea that I am toying with these days is to harness the power of HTML5, 2-way data binding in browser frameworks like Angular, and push some processing back to the browser. That way, you dont end up waiting in the line for someone else before you to finish. True distributed processing. But care must be taken in deciding what can be pushed and what not.
我最近在玩的一个有趣的想法是利用 HTML5 的强大功能,Angular 等浏览器框架中的 2 路数据绑定,并将一些处理推回浏览器。这样,您就不会在完成之前排队等候其他人。真正的分布式处理。但是在决定什么可以推动,什么不能推动时必须小心。
回答by Archimedes Trajano
Depends on the context.
取决于上下文。
TL;DR
TL; 博士
If you have the full data in your application server, do it in the application server.
如果您的应用程序服务器中有完整数据,请在应用程序服务器中进行。
If you have the full dataset that you need on the application server side already then it is better to do it on the application server side because those servers can scale horizontally. The most likely scenarios for this are:
如果您已经在应用程序服务器端拥有所需的完整数据集,那么最好在应用程序服务器端进行,因为这些服务器可以水平扩展。最可能的情况是:
- the data set you're retrieving from the database is small
- you cached the data on the application server side on startup
- You're doing event sourcing and you're building up the data in the application server side anyway.
- 您从数据库中检索的数据集很小
- 您在启动时将数据缓存在应用程序服务器端
- 您正在进行事件溯源,并且无论如何都在应用程序服务器端构建数据。
Don't do it on client side unless you can guarantee it won't impact the client devices.
不要在客户端执行此操作,除非您可以保证它不会影响客户端设备。
Databases themselves may be optimized, but if you can pull burden away from them you can reduce your costs overall because scaling the databases up is more expensive than scaling up application servers.
数据库本身可能会被优化,但如果您可以减轻它们的负担,您就可以降低总体成本,因为扩展数据库比扩展应用程序服务器的成本更高。