GBase 8c Join连接查询性能调优实例解析
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">原文链接:https://www.gbase.cn/community/post/3959</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">更加多</span>精彩内容<span style="color: black;">都在</span>南大通用GBase技术社区,南大通用致力于<span style="color: black;">作为</span>用户最信赖的数据库<span style="color: black;">制品</span>供应商。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">连接<span style="color: black;">查找</span>是关系型数据库中最<span style="color: black;">重点</span>的<span style="color: black;">查找</span><span style="color: black;">办法</span>之一,<span style="color: black;">包含</span>哈希连接、合并连接或嵌套循环连接等。GBase 8c数据库中Join<span style="color: black;">查找</span>性能<span style="color: black;">怎样</span>优化,下文<span style="color: black;">经过</span>举例子说明。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">1、<span style="color: black;">首要</span>创建表,并导入数据。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">创建表 departments和employees :</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">-- 创建<span style="color: black;">分部</span>表</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">CREATE TABLE departments (</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">dept_id INT PRIMARY KEY,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">dept_name VARCHAR(100)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">);</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">-- <span style="color: black;">插进</span><span style="color: black;">分部</span>数据</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">INSERT INTO departments (dept_id, dept_name) VALUES</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(1, HR),</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(2, Engineering),</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(3, Marketing);</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">创建表 employees</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">-- 创建员工表</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">CREATE TABLE employees (</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">emp_id INT PRIMARY KEY,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">emp_name VARCHAR(100),</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">dept_id INT,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">salary DECIMAL(10, 2),</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">FOREIGN KEY (dept_id) REFERENCES departments(dept_id)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">);</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">-- <span style="color: black;">插进</span>员工数据</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">INSERT INTO employees (emp_id, emp_name, dept_id, salary) VALUES</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(1, Alice, 1, 50000.00),</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(2, Bob, 2, 60000.00),</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(3, Carol, 3, 55000.00),</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(4, David, 1, 48000.00),</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(5, Eve, 2, 52000.00);</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">2、连接<span style="color: black;">查找</span>,将员工表中的emp_name与<span style="color: black;">分部</span>表中的dept_name对应起来,并<span style="color: black;">表示</span>执行计划。</p>原始<span style="color: black;">查找</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS) SELECT e.emp_name, d.dept_name </p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">FROM employees e</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">JOIN departments d ON e.dept_id = d.dept_id;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">执行计划可能<span style="color: black;">表示</span>类似于以下内容:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q2.itc.cn/images01/20240702/557e825793d54443a0bbc2c01c790aed.png" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在这个执行计划中:表中<span style="color: black;">仅有</span>5行数据,数据库执行计划走了hash join<span style="color: black;">显著</span>不对,<span style="color: black;">通常</span>连接数<span style="color: black;">少于</span>1000,nestloop (内循环嵌套连接)的性能<span style="color: black;">显著</span>会优于hash join(哈希连接),<span style="color: black;">由于</span>hash join 前先<span style="color: black;">必须</span>把小表和大表按连接字段做hash计算,<span style="color: black;">而后</span>分别对每一个hash 桶的结果进行连接。最后把结果汇总,思想有点类似快速排序算法的分而治之。</p><span style="color: black;">经过</span>hint优化后的<span style="color: black;">查找</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">-- 让执行计划走nestloop</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS) SELECT /*+ nestloop (e d) */ e.emp_name, d.dept_name</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">FROM employees e</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">JOIN departments d ON e.dept_id = d.dept_id;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">执行计划可能<span style="color: black;">表示</span>类似以下内容:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="//q5.itc.cn/images01/20240702/31aaa43e470145e0bc8481c7b7178f01.png" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在优化后的执行计划中:<span style="color: black;">运用</span>了 nestloop提示来强制<span style="color: black;">运用</span>内循环嵌套连接,<span style="color: black;">显著</span>sql的执行时间从0.419ms降到了0.170ms。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">3、分析<span style="color: black;">原由</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在原始执行计划中,可能<span style="color: black;">因为</span>优化器错误地<span style="color: black;">选取</span>了hash join,<span style="color: black;">引起</span>性能较差。而优化后的执行计划<span style="color: black;">经过</span> hint /*+ nestloop (e d) */ 提示强制<span style="color: black;">运用</span>了内循环嵌套连接,更适合<span style="color: black;">查找</span>中表数据较少的<span style="color: black;">状况</span>下连接操作。<span style="color: black;">因此呢</span><span style="color: black;">倘若</span>驱动表的数据量<span style="color: black;">少于</span>1000,<span style="color: black;">通常</span><span style="color: black;">选取</span>内循环嵌套,<span style="color: black;">能够</span><span style="color: black;">加强</span><span style="color: black;">查找</span>的效率。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">那样</span><span style="color: black;">那些</span>场景<span style="color: black;">能够</span><span style="color: black;">选取</span>哈希连接呢?对<span style="color: black;">平常</span>连接<span style="color: black;">运用</span>场景总结一下:</p>哈希连接 (Hash Join)适用场景:当连接的两个表中<span style="color: black;">最少</span>一个表较小,而另一个表<span style="color: black;">很强</span>时,<span style="color: black;">一般</span><span style="color: black;">选取</span>哈希连接。这是<span style="color: black;">由于</span>哈希连接的性能<span style="color: black;">重点</span>依赖于内存中构建哈希表的速度,而不是依赖于表的<span style="color: black;">体积</span>。当连接<span style="color: black;">要求</span>能够充分利用哈希算法的快速匹配特性时,例如等值连接 (e.g., JOIN ON table1.key = table2.key)。其<span style="color: black;">优良</span>在于:哈希连接在适当的<span style="color: black;">状况</span>下<span style="color: black;">能够</span><span style="color: black;">明显</span><span style="color: black;">加强</span>连接的性能,<span style="color: black;">尤其</span>是当内存和哈希函数的选择合适时。<span style="color: black;">重视</span>:<span style="color: black;">倘若</span>内存不足以容纳哈希表,性能可能会下降,<span style="color: black;">由于</span>会有频繁的磁盘 I/O 操作。合并连接 (Merge Join)适用场景:当连接的两个输入表<span style="color: black;">已然</span><span style="color: black;">根据</span>连接<span style="color: black;">要求</span>进行了排序时,合并连接是一个很好的<span style="color: black;">选取</span>。当连接<span style="color: black;">要求</span>是一个范围<span style="color: black;">查找</span>(例如 <=、>=、BETWEEN)时,合并连接<span style="color: black;">能够</span>有效地利用已排序的输入。其<span style="color: black;">优良</span>在于:合并连接<span style="color: black;">针对</span>已排序的输入表<span style="color: black;">拥有</span><span style="color: black;">有效</span>的连接性能,尤其在大型数据集上。<span style="color: black;">重视</span>:<span style="color: black;">倘若</span>输入数据<span style="color: black;">无</span>按连接<span style="color: black;">要求</span>排序,数据库可能<span style="color: black;">必须</span>额外的排序操作,这可能会<span style="color: black;">增多</span><span style="color: black;">查找</span>的成本。嵌套循环连接 (Nested Loop Join)适用场景:当其中一个表很小,而另一个表很大,<span style="color: black;">况且</span><span style="color: black;">无</span>适合哈希连接或合并连接的索引时,<span style="color: black;">一般</span>会<span style="color: black;">选取</span>嵌套循环连接。当连接<span style="color: black;">要求</span><span style="color: black;">不可</span>充分利用哈希或排序算法时,嵌套循环连接是一种简单有效的<span style="color: black;">选取</span>。其<span style="color: black;">优良</span>在于:<span style="color: black;">针对</span>较小的输入表<span style="color: black;">或</span>当连接<span style="color: black;">要求</span><span style="color: black;">选取</span><span style="color: black;">欠妥</span>时,嵌套循环连接<span style="color: black;">能够</span><span style="color: black;">供给</span>一种<span style="color: black;">靠谱</span>的连接方式。<span style="color: black;">重视</span>:嵌套循环连接的性能高度依赖于其中一个表的<span style="color: black;">体积</span>和索引的<span style="color: black;">运用</span><span style="color: black;">状况</span>。<span style="color: black;">倘若</span>其中一个表很大<span style="color: black;">或</span><span style="color: black;">无</span>适当的索引,性能可能会受到影响。<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">原文链接:https://www.gbase.cn/community/post/3959</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">更加多</span>精彩内容<span style="color: black;">都在</span>南大通用GBase技术社区,南大通用致力于<span style="color: black;">作为</span>用户最信赖的数据库<span style="color: black;">制品</span>供应商。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><a style="color: black;"><span style="color: black;">返回<span style="color: black;">外链论坛:www.fok120.com</span>,查看<span style="color: black;">更加多</span></span></a></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">责任编辑:网友投稿</span></p>
“BS”(鄙视的缩写)
页:
[1]