目前,我正面临一个性能问题(可能会导致以后的缩放问题)。我正在处理的应用程序非常复杂,并且运行在Server 2005上。我需要连接6-7个表才能得到所需的数据。到目前为止,每个表包含了100,000多行数据。不能更改数据库架构(必须保持原样)。所以我只能尽可能地优化。我想到了两件事:
进行筛选。
- Pros: will be able to scale easily by adding more app servers.
- Cons: more effort; I am not sure if responsiveness will be decreased.
- Pros: minimum effort
- Cons: when table records get bigger the problem will come back again
基本上,目前缓存对我来说不是一个解决方案(硬件问题、主机问题等等),这也是我最初没有提出来的原因。但是我知道缓存会给我带来什么好处,我已经多次使用它了。
发布于 2009-03-11 04:51:41
一般来说,在DBMS中进行连接。如果您在应用程序服务器中这样做,您就可以打赌,与编写DBMS的人员相比,您可以更好地优化连接,并且(进一步)您可以尽最大努力来抵消通过连接传输未连接数据的成本。
现在,如果要对两个宽表(假设它们是T1,具有宽度为W1的N1行和带宽度为N2的W2的T2 )进行跨乘积而不进行过滤,那么DBMS必须通过导线创建和发送N1 * N2 * (W1 + W2)字节,而您可以将表分别作为N1 * W1 + N2 *W2字节。如果N1 = N2 = 1M,W1 = W2 = 100,则为200 TB对200 MB的数据传输,这有利于在应用服务器中执行跨产品操作。但这对DBMS来说并不公平。大多数查询并没有那么愚蠢--它们连接列并应用条件,DBMS优化器将竭尽全力(并且自动)来最小化所做的工作。此外,它只将相关数据发送回您;它不需要发送不符合您的标准的所有行。
要展示另一个场景(有利于DBMS),请考虑T1的N1 =100万行宽度W1 = 100,而T2有N2 =100 K行宽度W2 = 50的情况。整数列上的两个表之间有一个联接,因此,在T1中,T2中的每一个表都有10行。假设您将所有的T1和T2下载到应用服务器:这需要N1 * W1 + N2 * W2 = 105 MB的数据。但是,筛选条件将数据限制在T2中的1/10行,对于T1中与T2中的一行匹配的每一行,实际上只有2行与筛选条件匹配。现在DBMS只会传输N2 * (W1 + W2) /5=3MB,这将节省数据库管理系统传输的数据超过100 MB。现在,如果您很聪明,只下载了N2 * W2 / 10 = 500 KB的数据,这些数据对应于T2中的值,那么您仍然必须让DBMS对希望从T1获得正确行到应用服务器的值进行T1的“半连接”。如果您只需要列的一个子集,则可以有另一组节省。而且DBMS倾向于有相当聪明的排序包;您需要在应用服务器中使用一个很好的排序包来以正确的顺序显示数据。
通常情况下,加入DBMS应该是一场自食其力的胜利。如果不是,那是因为您要求服务器做比它能处理的更多的工作。在这种情况下,您需要查看复制数据库服务器是否有意义,或者添加更多的内核、更多的网络带宽或更多的主内存是否可以完成这项工作。
发布于 2009-03-11 04:28:31
一般来说,我在谈到规模时,会考虑以下几点:
确保将获取的列限制在绝对不超过所需的范围内,特别是在连接许多表时,因为如果连接两个表所需的全部是被索引的列,数据库甚至可能根本不考虑表;可以只使用索引来执行连接。这减少了争用,提高了需要处理表的实际内容的较不优化的查询的性能,因为对表的查询较少。
所有关系数据库都有一个工具或功能来查看给定查询的查询执行计划。使用它。如果输出对你没有意义,那么学习它。这是了解数据库如何处理给定查询、将使用什么索引、在每个执行步骤中将遇到的估计(或实际)行数以及其他有趣内容的主要窗口。
一旦您了解了查询优化器实际用于查询的信息,并且所有的索引/统计信息/列选择都是正确的,那么您就可以更好地了解从哪里开始。如果您在数据库中尽其所能,您将不得不考虑使用数据的缓存,并使用更具体/更好的where子句来处理更少的表。
免责声明:我没有使用Server的直接经验,但在其他RDBMS(甲骨文、MySQL、PostgreSQL等)方面有很多经验。以及一般的建筑。
发布于 2009-03-11 04:40:00
通过在“不加入”场景中添加更多的服务器,您将获得更多的性能提升,无论是优化联接。你是对的-当你有更多的数据时,问题会回来。
最好的解决方案是使用内存缓存。您可以缓存表-表关系,这些关系的大小大多很小,而且不需要随时获取它们。
最佳方法是最小化连接,最小化选择,然后将很少更改的数据缓存到内存中。这会给你提振。
与微软(以及其他DB制造商)关于Joins的建议一样--尽可能地使用它们。根据我的经验-超过2-3个加入为复杂选择的顶级数字。
https://stackoverflow.com/questions/633211
复制相似问题