做建材商城网站WordPress海报图片插件

当前位置: 首页 > news >正文

做建材商城网站,WordPress海报图片插件,网站解析不过来,vue如何网站开发相信很多新手学了 函数的用法就不可避免的想把学到的东西用起来#xff0c;然而这个函数使用却有坑#xff0c; 在实际用的时候我发现一个简单的计算封装 #xff0c;不用函数和用函数执行耗时差太多了。 能避免列上进行函数则尽量避免#xff0c;这是在实际上遇到的坑 然而这个函数使用却有坑 在实际用的时候我发现一个简单的计算封装 不用函数和用函数执行耗时差太多了。 能避免列上进行函数则尽量避免这是在实际上遇到的坑 封装成函数和直接计算效果差太多。 行中函数(Scalar-valued functions)在 SQL Server 中的性能通常较差主要原因是它们在查询执行过程中被视为黑盒使得 SQL Server 优化器无法有效优化这些函数的执行。下面是一些针对行中函数优化的建议和替代方法 – 原始标量值函数 CREATE FUNCTION dbo.GetDiscount (ProductID INT) RETURNS DECIMAL(10, 2) AS BEGINDECLARE Discount DECIMAL(10, 2)SELECT Discount DiscountFROM ProductsWHERE ProductID ProductIDRETURN Discount END– 转换为内联表值函数 CREATE FUNCTION dbo.GetDiscountInline (ProductID INT) RETURNS TABLE AS RETURN (SELECT DiscountFROM ProductsWHERE ProductID ProductID ) 使用内联表值函数时你可以通过 JOIN 或 CROSS APPLY 来调用它而不会丢失性能优势。 SELECT p.ProductID, p.ProductName, d.Discount FROM Products p CROSS APPLY dbo.GetDiscountInline(p.ProductID) d 避免在查询中的列上使用标量函数 – 性能较差的写法 SELECT OrderID, dbo.CalculateTax(OrderAmount) AS TaxAmount FROM Orders– 性能更好的写法(将计算逻辑直接写入查询) SELECT OrderID, OrderAmount * 0.08 AS TaxAmount FROM Orders 使用计算列(Computed Columns) ALTER TABLE Orders ADD TaxAmount AS OrderAmount * 0.08 PERSISTED 使用 CASE 语句代替简单的函数 如果标量函数只涉及简单的逻辑判断可以考虑使用 CASE 语句直接在查询中实现。 – 使用 CASE 语句替代简单函数 SELECT OrderID, CASE WHEN OrderAmount 100 THEN OrderAmount * 0.1ELSE OrderAmount * 0.05END AS Discount FROM Orders 消除标量子查询 标量函数在 WHERE 或 JOIN 条件中使用时会影响性能可以考虑将其转换为 JOIN 操作。 – 性能较差的标量子查询 SELECT OrderID FROM Orders WHERE dbo.GetCustomerStatus(CustomerID) Active– 性能更好的 JOIN 替代 SELECT o.OrderID FROM Orders o JOIN Customers c ON o.CustomerID c.CustomerID WHERE c.Status Active 使用存储过程替代复杂的标量函数 对于复杂的逻辑可以使用存储过程来代替标量函数因为存储过程的执行效率通常较高。 标量值函数在 SQL Server 中的性能瓶颈通常可以通过以下方式解决 总结的优化 转换为内联表值函数(ITVF) 在查询中内联计算逻辑 使用计算列 使用 CASE 语句 使用存储过程 表值函数和内联表值函数的区别 CREATE FUNCTION dbo.GetOrdersByCustomer (CustomerID INT) RETURNS TABLE AS RETURN (SELECT OrderID, OrderDate, TotalAmountFROM OrdersWHERE CustomerID CustomerID ) 多语句表值函数(MSTVF) CREATE FUNCTION dbo.GetOrdersByCustomerMulti (CustomerID INT) RETURNS OrderTable TABLE (OrderID INT,OrderDate DATETIME,TotalAmount DECIMAL(18, 2) ) AS BEGININSERT INTO OrderTableSELECT OrderID, OrderDate, TotalAmountFROM OrdersWHERE CustomerID CustomerIDRETURN END 性能表现 内联表值函数(ITVF) 性能更高因为它们直接嵌入到调用查询中与视图类似。 SQL Server 优化器能够完全展开内联表值函数并将其优化为与查询其他部分一起执行的一个执行计划。 没有额外的计算开销因为它不使用表变量。 多语句表值函数(MSTVF) 性能通常较差因为 SQL Server 优化器无法提前知道函数内的具体逻辑。 由于使用了表变量可能会影响查询性能因为表变量不会生成统计信息这限制了优化器的能力。 对于复杂的逻辑和多个步骤的计算MSTVF 的灵活性更高但执行效率往往不如 ITVF。 适用场景 内联表值函数(ITVF) 适合简单的查询逻辑。 用于那些查询不需要复杂处理逻辑的场景。 性能要求较高的情况下应该优先选择使用 ITVF。 多语句表值函数(MSTVF) 适合复杂的业务逻辑和多步骤处理。 当需要多个 SQL 语句来生成最终结果时可以使用 MSTVF。 如果需要在函数中执行复杂的数据操作(如条件判断、循环等)MSTVF 是更好的选择。 SQL Server 优化器支持 ITVF因为是单个查询优化器可以将 ITVF 中的逻辑与主查询一起优化。SQL Server 能够生成更高效的执行计划。 MSTVF由于多语句表值函数的逻辑是一个黑盒优化器在执行之前无法知道其中包含的具体内容这会导致它生成一个次优的执行计划。 为啥标量值函数尽量避免使用 标量值函数(Scalar-valued functions)在 SQL Server 中的性能往往较差通常建议尽量避免使用。原因如下 1. 逐行执行 标量值函数在查询中被调用时会对每一行数据逐一执行。这种逐行处理(Row-by-row execution)方式会导致性能显著下降尤其是当查询结果集非常大时。相比之下SQL Server 通常更擅长处理批量操作。 示例假设有一个返回税额的标量函数 dbo.CalculateTax sql SELECT OrderID, dbo.CalculateTax(OrderAmount) AS TaxAmount FROM Orders 在此查询中如果 Orders 表有一百万行记录SQL Server 会为每一行调用一次 CalculateTax 函数导致性能极差。 2. 阻碍查询优化器优化 SQL Server 的查询优化器在生成查询计划时无法有效地优化标量值函数。标量函数的逻辑对于优化器来说是一个“黑盒”无法提前知道函数内的执行逻辑因此优化器无法进行充分的优化。这就限制了查询的性能提升。 相比之下内联表值函数(Inline Table-Valued Functions, ITVF)中的逻辑会被直接嵌入到查询计划中优化器可以根据整体查询来选择最优的执行计划。 3. 不会生成执行计划并行化 标量值函数通常会导致查询计划的并行化被禁用。SQL Server 优化器会倾向于将使用标量函数的查询设计为单线程执行这在处理大量数据时会显著降低性能。 4. 隐藏了真正的计算成本 标量值函数中的操作很容易被忽略因为它们的执行是隐藏在函数调用中的。这使得查询执行时间的分析和调优变得更加困难。使用标量函数时开发者可能低估了计算成本从而导致性能问题。 5. 带来额外的上下文切换开销 标量值函数在执行时会频繁地在 SQL Server 的上下文和函数自身的上下文之间进行切换。每次调用函数时都需要这种开销在处理大量数据时这种开销会被放大从而影响查询性能。 替代方案 为了避免标量值函数的性能问题可以考虑以下替代方案 使用内联表值函数(ITVF)它们的性能更好因为优化器可以将它们直接嵌入到主查询中进行优化。 将计算逻辑直接写在查询中将简单的计算逻辑内联到查询中避免使用函数封装。 使用计算列(Computed Columns)对于简单的计算可以在表中创建计算列并根据需要为其创建索引。 使用 CASE 语句对于简单的条件判断CASE 语句可以替代标量函数实现相同的逻辑。