Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 这更疯狂。所有这些(a)临时工作表和(b)临时工作表业务的临时工作表都是非规范化数据库的典型症状。或者无法理解数据的原貌,无法获取数据,无法创建不必要的工作表来满足您的需要。我并不是想让你改变这一点,这将是的第一选择,这将消除对整个混乱局面的需要 第二个选_Sql_Sql Server_Performance_Tsql - Fatal编程技术网

Sql 这更疯狂。所有这些(a)临时工作表和(b)临时工作表业务的临时工作表都是非规范化数据库的典型症状。或者无法理解数据的原貌,无法获取数据,无法创建不必要的工作表来满足您的需要。我并不是想让你改变这一点,这将是的第一选择,这将消除对整个混乱局面的需要 第二个选

Sql 这更疯狂。所有这些(a)临时工作表和(b)临时工作表业务的临时工作表都是非规范化数据库的典型症状。或者无法理解数据的原貌,无法获取数据,无法创建不必要的工作表来满足您的需要。我并不是想让你改变这一点,这将是的第一选择,这将消除对整个混乱局面的需要 第二个选,sql,sql-server,performance,tsql,Sql,Sql Server,Performance,Tsql,这更疯狂。所有这些(a)临时工作表和(b)临时工作表业务的临时工作表都是非规范化数据库的典型症状。或者无法理解数据的原貌,无法获取数据,无法创建不必要的工作表来满足您的需要。我并不是想让你改变这一点,这将是的第一选择,这将消除对整个混乱局面的需要 第二个选项是,查看是否可以从原始表格生成最终结果: -不使用工作台 -使用一个工作台 而不是两个工作台(16500和413000“记录”;这是两个指数非规范化级别) 第三个选项是,改善你的混乱状况。。。但首先你需要了解表演猪在哪里 但是查询的性能相当差

这更疯狂。所有这些(a)临时工作表和(b)临时工作表业务的临时工作表都是非规范化数据库的典型症状。或者无法理解数据的原貌,无法获取数据,无法创建不必要的工作表来满足您的需要。我并不是想让你改变这一点,这将是的第一选择,这将消除对整个混乱局面的需要

第二个选项是,查看是否可以从原始表格生成最终结果:
-不使用工作台
-使用一个工作台
而不是两个工作台(16500和413000“记录”;这是两个指数非规范化级别)

第三个选项是,改善你的混乱状况。。。但首先你需要了解表演猪在哪里

但是查询的性能相当差,正如您可能期望的那样,有如此多的自连接

胡说八道、连接和自连接不需要任何成本。问题在于,成本在于:

  • 您正在堆上操作

  • 没有主键

    • 仅这两项就意味着绩效未被考虑,也无法预期
  • 在联接中使用运算符和函数(而不是纯“=”)意味着服务器无法对搜索值做出合理的决定,因此您一直在扫描表

  • 表大小(在Dev/Test/Prod上可能不同)

  • 有效、可用的索引(或否)

  • 成本就在这四个项目上,堆在各个方面都非常缓慢,运营商也没有找到任何东西来缩小搜索范围;不是存在或不存在联接操作的事实

下一系列的问题就是你的做法

  • 您是否意识到“连接”是具体化的表;您不是在“加入”您是在动态地实现表格???没有什么是免费的:物质化有巨大的成本。你是如此专注于物质化而不知道成本,以至于你认为连接是问题所在。为什么呢

  • 在做出任何合理的编码决策之前,需要打开SHOWPLAN和STATISTICS IO。在开发时这样做(它还远没有准备好进行“测试”)。这会让你对桌子有个概念;连接(你所期望的与它所决定的,从混乱中);工作台(具体化)。CPU的高使用率不算什么,等你看到你的代码使用了疯狂的I/O后再说。如果你想争论在飞行中实现的成本,请便,但先发布展示计划

  • 请注意,具体化的表没有索引,因此它每次都对um“联接”进行表扫描

  • “按原样选择”所做的工作比它需要的多出数十倍(可能数百倍)。既然桌子就在那里,而且它没有移动,那么将它的另一个版本具体化是一件非常愚蠢的事情。因此,真正的问题是:

为什么我的SQL查询只有一个表和六个实体化版本,速度很慢?

.
如果您不确定,这意味着删除六个具体化的表,并将它们替换为与主表的纯联接

  • 如果你能接受分手,那就这么做吧。创建并加载此查询将首先使用的临时表(这意味着只有3个临时表用于聚合)。确保在正确的列上放置索引

  • 因此,可以用3个到主表的联接和3个到临时聚合表的联接来替换6个带的具体化表

  • 沿着这条线的某个地方,你已经确定你有笛卡尔积和复制品;您没有解决问题的原因(开发生成所需集合的代码),而是避免了所有这一切,让它充满了重复,并删除了不同的行。这会导致额外的工作台。解决这个问题。在合理地预期使用它们的选择是正确的之前,您必须首先使每个临时表(工作表、具体化表等)正确

  • 然后尝试选择

  • 我想这都是在WebData中运行的。如果不是,则将IsGreaterThan()放在此数据库中


  • 请提供UDF大于的DDL。如果这是使用表格,我们需要了解它

  • 请在CREATETABLE语句中提供声称的索引。它们可能是不正确的或更糟的,折叠起来不需要

  • 忘记身份或强制值,这个工作表堆的实际、真实、自然、逻辑PK是什么

  • 确保联接列上没有数据类型不匹配

  • 就我个人而言,我会羞于发布像你这样的代码。它是完全不可读取的。为了找出这里的问题,我所做的就是格式化它,使它可读。使代码可读是有原因的,例如,它允许您快速发现问题。你使用什么格式并不重要,但你必须格式化,而且你必须始终如一地这样做。请在再次发布之前将其清理干净,并附上所有相关DDL

  • 难怪你一直没有得到答案。您需要先做一些基础工作(showplan等),并准备代码,以便人类能够阅读,从而提供答案。

    SELECT
            MIN(units.MaxAccommodationAvailabilityPax) AS MaxAccommodationAvailabilityPax,
            MIN(units.MaxAccommodationAvailabilityAdults) AS MaxAccommodationAvailabilityAdults,
            StartDate AS DepartureDate,
            EndDate AS ReturnDate,
            DATEDIFF(DAY, StartDate, EndDate) AS Duration,
            MIN(units.accommodation_id) AS AccommodationID, 
            x.accommodation_unit_id AS AccommodationUnitID,
            SUM(Price) AS Price,
            MAX(num_pax) AS Occupancy,
            SUM(offer_discount) AS OfferSaving,
            MIN(date_correct) AS DateTimeCorrect,
            MIN(rooms_remaining) AS RoomsRemaining,
            MIN(CONVERT(int, dbo.IsGreaterThan(ISNULL(eta_available, 0)+ISNULL(nights_remaining_count, 0), 0))) 
                AS EtaAvailable
        FROM single_date_availability fp INNER JOIN (
            -- This gets max availability for the whole accommodation on the arrival date
            SELECT  accommodation_id, arrival_date,
                    CASE EtaAvailable 
                        WHEN 1 THEN 99
                        ELSE MaxAccommodationAvailabilityPax 
                        END AS MaxAccommodationAvailabilityPax,
                    CASE EtaAvailable
                        WHEN 1 THEN 99
                        ELSE MaxAccommodationAvailabilityAdults
                        END AS MaxAccommodationAvailabilityAdults
                FROM ( 
                    SELECT  accommodation_id, arrival_date,
                            SUM(MaximumOccupancy) 
                            MaxAccommodationAvailabilityPax,
                            SUM(MaximumAdults) MaxAccommodationAvailabilityAdults,
                            CONVERT(int, WebData.dbo.IsGreaterThan(SUM(EtaAvailable), -1))
                                AS EtaAvailable                 
                        FROM ( 
                            SELECT  accommodation_id,
                                    arrival_date,
                                    MIN(rooms_remaining*max_occupancy) as MaximumOccupancy,
                                    MIN(rooms_remaining*max_adults) as MaximumAdults, 
                                    MIN(ISNULL(eta_available, 0) + ISNULL(nights_remaining_count, 0) - 1)
                                        as EtaAvailable
                                FROM single_date_availability
                                GROUP BY accommodation_id, accommodation_unit_id, arrival_date
                                ) a 
                        GROUP BY accommodation_id, arrival_date
                        ) b
                ) units 
            ON fp.accommodation_id = units.accommodation_id 
            AND fp.arrival_date = units.arrival_date INNER JOIN (
                -- This gets every combination of StartDate and EndDate for each Unit/Occupancy
                SELECT  D.I.S.T.I.N.C.T a.accommodation_unit_id,
                        StartDate = a.arrival_date,
                        EndDate = b.arrival_date+1,
                        Duration = DATEDIFF(DAY, a.arrival_date, b.arrival_date)+1
                    FROM single_date_availability AS a INNER JOIN ( 
                        SELECT  accommodation_unit_id,
                                arrival_date 
                            FROM single_date_availability
                            ) AS b
                    ON a.accommodation_unit_id = b.accommodation_unit_id
                    AND DATEDIFF(DAY, a.arrival_date, b.arrival_date)+1 >= a.min_stay_nights
                    AND DATEDIFF(DAY, a.arrival_date, b.arrival_date)+1 <= (
                        CASE a.max_stay_nights 
                            WHEN 0 THEN 28 
                            ELSE a.max_stay_nights 
                            END
                    )
            ) x ON fp.accommodation_unit_id = x.accommodation_unit_id 
            AND fp.arrival_date >= x.StartDate 
            AND fp.arrival_date < x.EndDate
        GROUP BY x.accommodation_unit_id, StartDate, EndDate
        -- This ensures that all dates between StartDate and EndDate are actually available
        HAVING COUNT(*) = DATEDIFF(DAY, StartDate, EndDate)
    
    选择
    最小值(单位:MaxAccountationAvailabilityPax)为MaxAccountationAvailabilityPax,
    最小值(单位:MaxAccountationAvailabilityDults)为MaxAccountationAvailabilityDults,
    起始日期为出发日期,
    EndDate作为ReturnDate,
    DATEDIFF(天、开始日期、结束日期)作为持续时间,
    住宿id的最小值(单位住宿id),
    x.住宿单位id作为住宿起始,
    总和(价格)作为价格,
    入住率最高(人数),
    ?
    
    SELECT
        MIN(units.MaxAccommodationAvailabilityPax) AS MaxAccommodationAvailabilityPax,
        MIN(units.MaxAccommodationAvailabilityAdults) AS MaxAccommodationAvailabilityAdults,
        StartDate AS DepartureDate,
        EndDate AS ReturnDate,
        DATEDIFF(DAY, StartDate, EndDate) AS Duration,
        MIN(units.accommodation_id) AS AccommodationID, 
        x.accommodation_unit_id AS AccommodationUnitID,
        SUM(Price) AS Price,
        MAX(num_pax) AS Occupancy,
        SUM(offer_discount) AS OfferSaving,
        MIN(date_correct) AS DateTimeCorrect,
        MIN(rooms_remaining) AS RoomsRemaining,
        MIN(CONVERT(int, dbo.IsGreaterThan(ISNULL(eta_available, 0)+ISNULL(nights_remaining_count, 0), 0))) AS EtaAvailable
    FROM single_date_availability fp
    INNER JOIN (
        /* This gets max availability for the whole accommodation on the arrival date */
        SELECT accommodation_id, arrival_date,
            CASE EtaAvailable WHEN 1 THEN 99 ELSE MaxAccommodationAvailabilityPax END AS MaxAccommodationAvailabilityPax,
            CASE EtaAvailable WHEN 1 THEN 99 ELSE MaxAccommodationAvailabilityAdults END AS MaxAccommodationAvailabilityAdults
        FROM (SELECT accommodation_id, arrival_date, SUM(MaximumOccupancy) MaxAccommodationAvailabilityPax, SUM(MaximumAdults) MaxAccommodationAvailabilityAdults,
                CONVERT(int, WebData.dbo.IsGreaterThan(SUM(EtaAvailable), -1)) AS EtaAvailable                 
                FROM (SELECT accommodation_id, arrival_date, MIN(rooms_remaining*max_occupancy) as MaximumOccupancy,
                        MIN(rooms_remaining*max_adults) as MaximumAdults, MIN(ISNULL(eta_available, 0) + ISNULL(nights_remaining_count, 0) - 1) as EtaAvailable
                        FROM single_date_availability
                        GROUP BY accommodation_id, accommodation_unit_id, arrival_date) a 
                GROUP BY accommodation_id, arrival_date) b
    ) units ON fp.accommodation_id = units.accommodation_id AND fp.arrival_date = units.arrival_date
    INNER JOIN (
        /* This gets every combination of StartDate and EndDate for each Unit/Occupancy */
        SELECT DISTINCT a.accommodation_unit_id, StartDate = a.arrival_date,
            EndDate = b.arrival_date+1, Duration = DATEDIFF(DAY, a.arrival_date, b.arrival_date)+1
            FROM single_date_availability AS a
            INNER JOIN (SELECT accommodation_unit_id, arrival_date FROM single_date_availability) AS b
            ON a.accommodation_unit_id = b.accommodation_unit_id
                AND DATEDIFF(DAY, a.arrival_date, b.arrival_date)+1 >= a.min_stay_nights
                AND DATEDIFF(DAY, a.arrival_date, b.arrival_date)+1 <= (CASE a.max_stay_nights WHEN 0 THEN 28 ELSE a.max_stay_nights END)
    ) x ON fp.accommodation_unit_id = x.accommodation_unit_id AND fp.arrival_date >= x.StartDate AND fp.arrival_date < x.EndDate
    GROUP BY x.accommodation_unit_id, StartDate, EndDate
    /* This ensures that all dates between StartDate and EndDate are actually available */
    HAVING COUNT(*) = DATEDIFF(DAY, StartDate, EndDate)
    
    AND DATEDIFF(DAY , a.arrival_date , b.arrival_date) + 1 >= a.min_stay_nights
    AND DATEDIFF(DAY , a.arrival_date , b.arrival_date) + 1 <= (CASE a.max_stay_nights WHEN 0 THEN 28 ELSE a.max_stay_nights END)
    
    and a.min_stay_nights<=DATEDIFF(DAY , a.arrival_date , b.arrival_date)
    and (CASE a.max_stay_nights WHEN 0 THEN 28 ELSE a.max_stay_nights END)>=DATEDIFF(DAY , a.arrival_date , b.arrival_date) + 1
    
    SELECT
            MIN(units.MaxAccommodationAvailabilityPax) AS MaxAccommodationAvailabilityPax,
            MIN(units.MaxAccommodationAvailabilityAdults) AS MaxAccommodationAvailabilityAdults,
            StartDate AS DepartureDate,
            EndDate AS ReturnDate,
            DATEDIFF(DAY, StartDate, EndDate) AS Duration,
            MIN(units.accommodation_id) AS AccommodationID, 
            x.accommodation_unit_id AS AccommodationUnitID,
            SUM(Price) AS Price,
            MAX(num_pax) AS Occupancy,
            SUM(offer_discount) AS OfferSaving,
            MIN(date_correct) AS DateTimeCorrect,
            MIN(rooms_remaining) AS RoomsRemaining,
            MIN(CONVERT(int, dbo.IsGreaterThan(ISNULL(eta_available, 0)+ISNULL(nights_remaining_count, 0), 0))) 
                AS EtaAvailable
        FROM single_date_availability fp INNER JOIN (
            -- This gets max availability for the whole accommodation on the arrival date
            SELECT  accommodation_id, arrival_date,
                    CASE EtaAvailable 
                        WHEN 1 THEN 99
                        ELSE MaxAccommodationAvailabilityPax 
                        END AS MaxAccommodationAvailabilityPax,
                    CASE EtaAvailable
                        WHEN 1 THEN 99
                        ELSE MaxAccommodationAvailabilityAdults
                        END AS MaxAccommodationAvailabilityAdults
                FROM ( 
                    SELECT  accommodation_id, arrival_date,
                            SUM(MaximumOccupancy) 
                            MaxAccommodationAvailabilityPax,
                            SUM(MaximumAdults) MaxAccommodationAvailabilityAdults,
                            CONVERT(int, WebData.dbo.IsGreaterThan(SUM(EtaAvailable), -1))
                                AS EtaAvailable                 
                        FROM ( 
                            SELECT  accommodation_id,
                                    arrival_date,
                                    MIN(rooms_remaining*max_occupancy) as MaximumOccupancy,
                                    MIN(rooms_remaining*max_adults) as MaximumAdults, 
                                    MIN(ISNULL(eta_available, 0) + ISNULL(nights_remaining_count, 0) - 1)
                                        as EtaAvailable
                                FROM single_date_availability
                                GROUP BY accommodation_id, accommodation_unit_id, arrival_date
                                ) a 
                        GROUP BY accommodation_id, arrival_date
                        ) b
                ) units 
            ON fp.accommodation_id = units.accommodation_id 
            AND fp.arrival_date = units.arrival_date INNER JOIN (
                -- This gets every combination of StartDate and EndDate for each Unit/Occupancy
                SELECT  D.I.S.T.I.N.C.T a.accommodation_unit_id,
                        StartDate = a.arrival_date,
                        EndDate = b.arrival_date+1,
                        Duration = DATEDIFF(DAY, a.arrival_date, b.arrival_date)+1
                    FROM single_date_availability AS a INNER JOIN ( 
                        SELECT  accommodation_unit_id,
                                arrival_date 
                            FROM single_date_availability
                            ) AS b
                    ON a.accommodation_unit_id = b.accommodation_unit_id
                    AND DATEDIFF(DAY, a.arrival_date, b.arrival_date)+1 >= a.min_stay_nights
                    AND DATEDIFF(DAY, a.arrival_date, b.arrival_date)+1 <= (
                        CASE a.max_stay_nights 
                            WHEN 0 THEN 28 
                            ELSE a.max_stay_nights 
                            END
                    )
            ) x ON fp.accommodation_unit_id = x.accommodation_unit_id 
            AND fp.arrival_date >= x.StartDate 
            AND fp.arrival_date < x.EndDate
        GROUP BY x.accommodation_unit_id, StartDate, EndDate
        -- This ensures that all dates between StartDate and EndDate are actually available
        HAVING COUNT(*) = DATEDIFF(DAY, StartDate, EndDate)