准备数据每次都有交换或多个连接?

时间:2014-10-10 11:24:15

标签: sql-server sql-server-2008

请让我用一个例子解释一下:

您需要向客户展示有关某些产品价格的实际信息。最终价格受客户权益,地点,产品运输方式和当前产品供应商的影响。

产品数量超过100亿。此外,您应该以不同的货币显示价格。最后一个问题是,供应商每天都会向他们的产品发送大量价格,由于那里有很多头寸,你可以全天申请(更新),而客户不想等到你更新他们所有人都想知道现在的价格(我知道这是不可能的,但我的意思是 - 顾客不应该看到这样的信息:"对不起,你要等到所有的价格都是更新"。)

我想要什么

我想划分一个表ThePrice (productId, vendorId, usdPrice),每次客户提出这样的查询时都会使用该表

select .... from ThePrice p
  inner join Vendors v ...
  inner join VendorsPrices vp ...
  inner join UserRatio ur ...
  left join ShippingRatio ...
  inner join Currencies ...
  inner join PriceDependsOnLocation ...

分为两个相似的表格

FirstPrice (productId, vendorId, usdPrice, user1Ratio, user2Ratio, user3Ratio, shipppingRatio, euroPrice, localPrice)

SecondPrice(productId, vendorId, usdPrice, user1Ratio, user2Ratio, user3Ratio, shipppingRatio, euroPrice, localPrice)

其中

userXRatio - 客户权益级别的所有可能因素。 usdPrice上的附加乘法。 shippingRatio - 定义客户是否需要发货。 usdPrice上的附加乘法。 euroPricelocalPrice - 是以今天报价单的不同货币显示的价格。

可能看起来像

if (@OneHourPassed = 1) 
  select ... from FirstPrice
else
  select ... from SecondPrice

--not the best way but just to point out

现在所有这些参数都会重新计算,因为价格可能会在每次下一次查询时更改,此时它会更新为ThePrice表。没有缓存。

这意味着,我不时会收到锁定,因为当客户搜索产品时,它们也会在一整天内更新。想象一下 - 在一分钟内,客户可能会有2000个查询,并且会更新供应商的一两个价格。 在同一张桌子上!

我想使用准备好的数据:当FirstPrice表用于READ时,SecondPrice表用于WRITE - 来更新价格。在某个时刻他们交换,即在一个小时内。

我只是想知道 - 应用它的机制是什么。使用IF-s?还是有另一种更优雅的方式吗?

2 个答案:

答案 0 :(得分:0)

你的问题在太空中听起来有点太过分了,但是从我能捕捉到的,也许这样的事情可以帮助你。

 create table FirstPrice (
    productId int, 
    vendorId int, 
    usdPrice money, 
    user1Ratio int, 
    user2Ratio int, 
    user3Ratio int, 
    shipppingRatio int, 
    euroPrice money, 
    localPrice money
)

 create table SecondPrice (
    productId int, 
    vendorId int, 
    usdPrice money, 
    user1Ratio int, 
    user2Ratio int, 
    user3Ratio int, 
    shipppingRatio int, 
    euroPrice money, 
    localPrice money
)


 CREATE TABLE LastExecution(execDate datetime default getdate());
 insert into LastExecution(execDate) values (default);
 GO

CREATE PROCEDURE SP_PRICE
AS
BEGIN
  DECLARE @DATE DATETIME
  SELECT @DATE=EXECDATE FROM LastExecution

  IF (DATEDIFF(HOUR,@DATE,GETDATE())>0) 
    BEGIN
      insert into LastExecution(execDate) values (default);
      SELECT 'Second' as [table],* FROM SecondPrice;
    END
  ELSE
    BEGIN
        SELECT 'First' as [table],* FROM FirstPrice;
    END
END;

答案 1 :(得分:0)

我猜这种决定是两种方式:

1)使用Partitions,但购买企业版,我仍然不了解切换表的时刻

2)使用可能View的{​​{1}},但你必须创建一个控制表,你应该在那里持有一个用于切换表的标志并且有查询中到处都是这个脚本:

Alter

或另外建议的方式

while exists(select 1 from ControlTable where SwitchNow = 1)
begin
  waitfor delay '00:00:00.005'
end
-- this is for client-queries, who should release the View from being Altered

但我认为,对于sql-planner来说这不是一个好主意,还是我看错了?因为如果我错了,那么这是最好的方式。