存储过程部件优化

时间:2015-04-30 22:08:30

标签: sql-server stored-procedures sql-server-2008-r2 query-optimization

我有一个存储过程

CREATE PROCEDURE [dbo].[MyProcedure]
-- Add the parameters for the stored procedure here
@xml XML
AS
BEGIN
    SET FMTONLY OFF
    declare @idoc INT; -- table(CentreId bigint, LanguageId int)
    EXEC sp_xml_preparedocument @idoc OUTPUT, @xml

--declare @LangCentre table (CentreId bigint, LanguageId int) 
CREATE TABLE #LangCentre
(
   CentreId bigint, 
   LanguageId INT
)

INSERT into #LangCentre (CentreId, LanguageId)(
SELECT * from OPENXML (@idoc, '/T/R', 2) WITH (CentreId BIGINT 'C', LanguageId int 'L'))

CREATE TABLE #LangCentreCTranslation
(
   CentreId BIGINT, 
   LanguageId INT,
   CentreTranslationId BIGINT
)    

INSERT into #LangCentreCTranslation (CentreId, LanguageId, CentreTranslationId)(
    SELECT 
    lc.CentreId,
    lc.LanguageId,      
    CASE WHEN ct.id IS NULL THEN ct2.id ELSE ct.id END AS CentreTranslationId 
    FROM #LangCentre lc
    LEFT JOIN dbo.CentreTranslation ct ON ct.centre_id = lc.CentreId AND ct.language_id = lc.LanguageId
    LEFT JOIN dbo.CentreTranslation ct2 ON ct2.centre_id = lc.CentreId and ct2.language_id = 1
)

SELECT  
lcct.CentreTranslationId,       
lcct.LanguageId,
lcct.CentreId AS CentreID ,
ptBusinessCentre.about AS BusinessCentreDescription,
ptBusinessCentre.meta_title AS BusinessCentreMetaTitle,
ptBusinessCentre.meta_keywords AS BusinessCentreMetaKeywords,
ptBusinessCentre.meta_description AS BusinessCentreMetaDescription,

ptOffice.about AS OfficeDescription,
ptOffice.meta_title AS OfficeMetaTitle,
ptOffice.meta_keywords AS OfficeMetaKeywords,
ptOffice.meta_description AS OfficeMetaDescription,

ptVirtualOffice.about AS VirtualOfficeDescription,
ptVirtualOffice.meta_title AS VirtualOfficeMetaTitle,
ptVirtualOffice.meta_keywords AS VirtualOfficeMetaKeywords,
ptVirtualOffice.meta_description AS VirtualOfficeMetaDescription,

ptMeetingRoom.about AS MeetingRoomDescription,
ptMeetingRoom.meta_title AS MeetingRoomMetaTitle,
ptMeetingRoom.meta_keywords AS MeetingRoomMetaKeywords,
ptMeetingRoom.meta_description AS MeetingRoomMetaDescription,

ptBusinessLounge.about AS BusinessLoungeDescription,
ptBusinessLounge.meta_title AS BusinessLoungeMetaTitle,
ptBusinessLounge.meta_keywords AS BusinessLoungeMetaKeywords,
ptBusinessLounge.meta_description AS BusinessLoungeMetaDescription,

ptDayOffice.about AS DayOfficeDescription,
ptDayOffice.meta_title AS DayOfficeMetaTitle,
ptDayOffice.meta_keywords AS DayOfficeMetaKeywords,
ptDayOffice.meta_description AS DayOfficeMetaDescription,

ptVideoConferencing.about AS VideoConferencingDescription,
ptVideoConferencing.meta_title AS VideoConferencingMetaTitle,
ptVideoConferencing.meta_keywords AS VideoConferencingMetaKeywords,
ptVideoConferencing.meta_description AS VideoConferencingMetaDescription,

ptManagedOfficeSolutions.about AS ManagedOfficeSolutionsDescription,    
ptManagedOfficeSolutions.meta_title AS ManagedOfficeSolutionsMetaTitle, 
ptManagedOfficeSolutions.meta_keywords AS ManagedOfficeSolutionsMetaKeywords,   
ptManagedOfficeSolutions.meta_description AS ManagedOfficeSolutionsMetaDescription, 

ptTelecommunications.about AS TelecommunicationsDescription,    
ptTelecommunications.meta_title AS TelecommunicationsMetaTitle, 
ptTelecommunications.meta_keywords AS TelecommunicationsMetaKeywords,   
ptTelecommunications.meta_description AS TelecommunicationsMetaDescription, 

--

ctContact.manager AS CentreManager,
ctContact.area_director AS AreaDirector,
ctContact.rmm AS RMM,
ctContact.operations_director AS OperationsDirector,
ctContact.financial_controller AS FinancialController,
ctContact.sales_fax_line AS SalesFaxLine,
ctContact.agents_hotline AS AgentsHotline,
ctContact.emergency_phone AS EmergencyPhone,
ctContact.emergency_pager AS EmergencyPager,
ctContact.receptionist_phone AS ReceptionistPhone,
ctContact.rsc_speed_dials AS RscSpeedDials,
ctContact.toll_free AS TollFree,
ctContact.voicemail_server AS VoicemailServer,
ctContact.additional_phone AS AdditionalPhone,
ctContact.additional_fax AS AdditionalFax,

ctContact.centre_manager_email as CentreManagerEmail,
ctContact.area_director_address as AreaDirectorEmail,

ctRooms.number_of_offices AS NumberOfOffices,
ctRooms.number_of_meeting_rooms AS NumberOfMeetingRooms,
ctRooms.number_of_training_rooms AS NumberOfTrainingRooms,
ctRooms.number_of_conference_rooms AS NumberOfConferenceRooms,
ctRooms.number_of_workstations AS NumberOfWorkstations,
ctRooms.number_of_floors AS NumberOfFloors,
ctRooms.number_of_parking_spaces AS NumberOfParkingSpaces,
ctRooms.parking_costs AS ParkingCosts,
ctRooms.floor_area AS FloorArea,
ctRooms.floorplan AS Floorplan,

ctOpeningHours.monday_opening AS MondayOpening,
ctOpeningHours.monday_closing AS MondayClosing,
ctOpeningHours.tuesday_opening AS TuesdayOpening,
ctOpeningHours.tuesday_closing AS TuesdayClosing,
ctOpeningHours.wednesday_opening AS WednesdayOpening,
ctOpeningHours.wednesday_closing AS WednesdayClosing,
ctOpeningHours.thursday_opening AS ThursdayOpening,
ctOpeningHours.thursday_closing AS ThursdayClosing,
ctOpeningHours.friday_opening AS FridayOpening,
ctOpeningHours.friday_closing AS FridayClosing,
ctOpeningHours.saturday_opening AS SaturdayOpening,
ctOpeningHours.saturday_closing AS SaturdayClosing,
ctOpeningHours.sunday_opening AS SundayOpening,
ctOpeningHours.sunday_closing AS SundayClosing,
ctOpeningHours.timezone_id AS TimezoneId,

ctLounge.opening_times_text AS OpeningTimesText,
ctLounge.number_of_armchairs AS NumberOfArmchairs,
ctLounge.number_of_seats_in_library as NumberOfSeatsInLibrary,
ctLounge.number_of_bar_stools as NumberOfBarStools,
ctLounge.number_of_other_seats as NumberOfOtherSeats,
ctLounge.number_of_thinkpods AS NumberOfThinkpods,
ctLounge.number_of_mac_pc_bars AS NumberOfMacPcBars,
ctLounge.number_of_flatscreen_tvs AS NumberOfFlatScreenTvs,
ctLounge.number_of_newspapers AS NumberOfNewspapers,

--
ctLounge.lounge_type as LoungeType,
ctLounge.alternative_to_businesslounge as AlternativeToBL,
ctLounge.last_refubrishment_date as LastRefurbishmentDate,
ctLounge.lounge_location_in_centre as LocationInCentre,
ctLounge.lounge_visible_from_outside as VisibleFromOutside,
ctLounge.signage_to_advertise as SignageOutsideToAdvertise,
ctLounge.reason_for_no_advertisment as ReasonForNoAdvertisement,
ctLounge.type_of_access_control as TypeOfAccessControl,
ctLounge.monday_opening as LoungeMondayOpening,
ctLounge.monday_closing as LoungeMondayClosing,
ctLounge.tuesday_opening as LoungeTuesdayOpening,
ctLounge.tuesday_closing as LoungeTuesdayClosing,
ctLounge.wednesday_opening as LoungeWednesdayOpening,
ctLounge.wednesday_closing as LoungeWednesdayClosing,
ctLounge.thursday_opening as LoungeThursdayOpening,
ctLounge.thursday_closing as LoungeThursdayClosing,
ctLounge.friday_opening as LoungeFridayOpening,
ctLounge.friday_closing as LoungeFridayClosing,
ctLounge.saturday_opening as LoungeSaturdayOpening,
ctLounge.saturday_closing as LoungeSaturdayClosing,
ctLounge.sunday_opening as LoungeSundayOpening,
ctLounge.sunday_closing as LoungeSundayClosing,
ctLounge.type_of_location as TypeOfLocation,
ctLounge.parking_facilities as ParkingFacilities,
ctLounge.have_to_pass_through_security as HaveToPassThroughSecurity,
ctLounge.is_advanced_security_notification_requiered as IsAdvancedSecurityNotificationRequiered,
ctLounge.business_lounge_floor as BusinessLoungeFloor,
ctLounge.type_of_room as TypeOfRoom,
ctLounge.suitable_for_disabled as SuitableForDisabled,
ctLounge.does_directly_receive_light as DoesDirectlyReceiveLight,
ctLounge.airconditioning as Airconditioning,
ctLounge.is_wifi_available as IsWifiAvailable,
ctLounge.is_ethernet_available as IsEthernetAvailable,
ctLounge.number_of_computers as NumberOfComputers,
ctLounge.other_internet_access as OtherInternetAccess,
ctLounge.are_beverages_available as AreBeveragesAvailable,
ctLounge.type_of_coffee_available as TypeOfCoffeeAvailable,
ctLounge.copy_fax_print_facilities as CopyFaxPrintFacilities,
ctLounge.business_support as BusinessSupport,
ctLounge.mobile_charging_points as MobileChargingPoints,
ctLounge.newspapers_and_magazines as NewspapersAndMagazines,
ctLounge.bathroom_facilities_available as BathroomFacilitiesAvailable,
ctLounge.showers_available as ShowersAvailable,
(case 
when ctLounge.grade=1 then 'Grade A'
when ctLounge.grade=2 then 'Grade B'
when ctLounge.grade=3 then 'Grade C'
when ctLounge.grade=4 then 'Ungraded'
else 'No Value' end) as Grade,

--

ctOtherInfo.bank_name AS BankName,
ctOtherInfo.bank_address AS BankAddress,
ctOtherInfo.bank_account_number AS BankAccountNumber,
ctOtherInfo.bank_sort_code AS BankSortCode,
ctOtherInfo.bank_swift_code AS BankSwiftCode,
ctOtherInfo.vc_equipment AS VcEquipment,
ctOtherInfo.vc_equipment_working AS VcEquipmentWorking,
ctOtherInfo.isdn AS ISDN,
ctOtherInfo.vc_contact AS VcContact,
ctOtherInfo.vc_phone AS VcPhone,
ctOtherInfo.equipment_make AS EquipmentMake,
ctOtherInfo.speed AS Speed,
ctOtherInfo.additional_charges AS AdditionalCharges,
ctOtherInfo.room_capacity AS RoomCapacity,
ctOtherInfo.out_of_hours_vc_contact AS OutOfHoursVcContact,
ctOtherInfo.vc_room_names AS VcRoomNames,
ctOtherInfo.maximum_bandwidth AS MaximumBandwidth,
ctOtherInfo.floodgate_installed AS FloodgateInstalled,
ctOtherInfo.encryption AS Encryption,
ctOtherInfo.underfloor_cat5_cabling AS UnderfloorCat5Cabling,
ctOtherInfo.lockable_comms_rack_space AS LockableCommsRackSpace,

isNULL(ct.name, cn.name) as CentreName,
ct.name as TranslatedName,
ct.address_line_1 as Address1,
ct.address_line_2 as Address2,
ct.address_line_3 as Address3,
ct.city as Town,
ct.postcode as PostalCode,
ct.country as Country,
ct.county as State,


cn.number as Number,
cn.url as Url,
cn.virtual_tour_url as VirtualTourUrl,
(CASE WHEN status.cnt>0 THEN 1 ELSE 0 END) AS ShowCentre,
cnInactivityReason.[description] as ReasonForNotShowing,
cn.alternate_name as AlternateName,
cn.date_opened as OpeningDate,
cn.closed as Closed,
cn.date_closed as DateClosed,
cn.phone as Phone,
cn.fax as Fax,
cn.email as Email,
cn.position.Lat as Latitude,
cn.position.Long as Longtitude,
images.cnt as ImagesCount,
cn.area as Area,
cn.sales_cluster as SalesCluster,
cn.is_additionl_security_check_required as AdditionalSecurityCheck,
ct.country as TranslatedCountry,
cn.virtual_tour as VirtualTour,
ct.about as OriginalDescription,
ct.directions as directions,
cn.centre_profile_id as CentreProfileId,
ct.amenities as AmenitiesFreeText,

STUFF((SELECT ',' + convert(VARCHAR(10), feature_id) FROM dbo.CentreFeature cf LEFT JOIN #LangCentreCTranslation lcct ON cf.Centre_Id = lcct.Centreid ORDER BY feature_id FOR XML PATH('')), 1, 1, '') as FeatureIds,

STUFF((SELECT ',' + convert(VARCHAR(10), brand_id) FROM dbo.CentreBrand cf LEFT JOIN #LangCentreCTranslation lcct ON cf.Centre_Id = lcct.Centreid ORDER BY brand_id FOR XML PATH('')), 1, 1, '') as BrandIds

FROM #LangCentreCTranslation lcct
INNER JOIN dbo.Centre cn on lcct.CentreId = cn.id
LEFT JOIN dbo.CentreTranslation ct ON lcct.CentreTranslationId = ct.id
LEFT JOIN dbo.ProductTranslation ptBusinessCentre ON lcct.CentreTranslationId = ptBusinessCentre.centre_translation_id AND ptBusinessCentre.product_id = 1
LEFT JOIN dbo.ProductTranslation ptOffice ON lcct.CentreTranslationId = ptOffice.centre_translation_id AND ptOffice.product_id = 2
LEFT JOIN dbo.ProductTranslation ptVirtualOffice ON lcct.CentreTranslationId = ptVirtualOffice.centre_translation_id AND ptVirtualOffice.product_id = 3
LEFT JOIN dbo.ProductTranslation ptMeetingRoom ON lcct.CentreTranslationId = ptMeetingRoom.centre_translation_id AND ptMeetingRoom.product_id = 4
LEFT JOIN dbo.ProductTranslation ptBusinessLounge ON lcct.CentreTranslationId = ptBusinessLounge.centre_translation_id AND ptBusinessLounge.product_id = 5
LEFT JOIN dbo.ProductTranslation ptDayOffice ON lcct.CentreTranslationId = ptDayOffice.centre_translation_id AND ptDayOffice.product_id = 6
LEFT JOIN dbo.ProductTranslation ptVideoConferencing ON lcct.CentreTranslationId = ptVideoConferencing.centre_translation_id AND ptVideoConferencing.product_id = 11
LEFT JOIN dbo.ProductTranslation ptTelecommunications ON lcct.CentreTranslationId = ptTelecommunications.centre_translation_id AND ptTelecommunications.product_id = 12
LEFT JOIN dbo.ProductTranslation ptManagedOfficeSolutions ON lcct.CentreTranslationId = ptManagedOfficeSolutions.centre_translation_id AND ptManagedOfficeSolutions.product_id = 14

LEFT JOIN dbo.CentreContact ctContact ON lcct.CentreId = ctContact.centre_id
LEFT JOIN dbo.CentreRooms ctRooms ON lcct.CentreId = ctRooms.centre_id
LEFT JOIN dbo.CentreOpeningHours ctOpeningHours ON lcct.CentreId = ctOpeningHours.centre_id
LEFT JOIN dbo.CentreLounge ctLounge ON lcct.CentreId = ctLounge.centre_id
LEFT JOIN dbo.CentreOtherInfo ctOtherInfo ON lcct.CentreId = ctOtherInfo.centre_id

LEFT JOIN (SELECT centre_id, COUNT (*) as cnt from dbo.CentreStatus GROUP BY centre_id) status ON status.centre_id=lcct.CentreId
LEFT JOIN dbo.CentreInactivityReason cnInactivityReason ON cn.inactivity_reason = cnInactivityReason.id
LEFT JOIN (SELECT centre_id, COUNT (*) as cnt from dbo.Image2Centre GROUP BY centre_id) images ON images.centre_id=lcct.CentreId

ORDER BY isNULL(ct.name, cn.name)

DROP TABLE #LangCentreCTranslation
DROP TABLE #LangCentre

EXEC sp_xml_removedocument @idoc
-- Insert statements for procedure here


END

SP处理大约2700条记录。此SP中的问题是,如果我不禁用

STUFF((SELECT ',' + convert(VARCHAR(10), feature_id) FROM dbo.CentreFeature cf LEFT JOIN #LangCentreCTranslation lcct ON cf.Centre_Id = lcct.Centreid ORDER BY feature_id FOR XML PATH('')), 1, 1, '') as FeatureIds,

STUFF((SELECT ',' + convert(VARCHAR(10), brand_id) FROM dbo.CentreBrand cf LEFT JOIN #LangCentreCTranslation lcct ON cf.Centre_Id = lcct.Centreid ORDER BY brand_id FOR XML PATH('')), 1, 1, '') as BrandIds

这个SP将在大约13分钟内执行,但是上面的行被注释\删除它将在~30秒内执行,我如何优化SP的这些特定部分以提高它们的性能。如果需要,我可以提供表格结构\执行计划(不知道如何附加文件)。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

如果查看以下两行,您会发现它们与父查询无关。

STUFF((SELECT ',' + convert(VARCHAR(10), feature_id) 
FROM dbo.CentreFeature cf 
LEFT JOIN #LangCentreCTranslation lcct
ON cf.Centre_Id = lcct.Centreid ORDER BY feature_id FOR XML PATH('')), 1, 1, '') as FeatureIds,

STUFF((SELECT ',' + convert(VARCHAR(10), brand_id) 
FROM dbo.CentreBrand cf 
LEFT JOIN #LangCentreCTranslation lcct 
ON cf.Centre_Id = lcct.Centreid ORDER BY brand_id FOR XML PATH('')), 1, 1, '') as BrandIds

这些查询不会引用父查询中的任何列。如果这是您想要的,您可以创建两个变量并从这些查询中分配值,并使用最终SELECT中的变量。

我认为你正在努力完成这样的事情。

STUFF((SELECT ',' + convert(VARCHAR(10), feature_id) 
FROM dbo.CentreFeature cf 
WHERE cf.Centre_Id = lcct.Centreid ORDER BY feature_id FOR XML PATH('')), 1, 1, '') as FeatureIds,

STUFF((SELECT ',' + convert(VARCHAR(10), brand_id) 
FROM dbo.CentreBrand cf 
WHERE cf.Centre_Id = lcct.Centreid ORDER BY brand_id FOR XML PATH('')), 1, 1, '') as BrandIds

请注意,我已删除JOIN并添加了WHERE子句以从父查询中引用lcct.Centreid的值,并使此子查询成为共同相关的子查询

您可以选择在将数据插入#LangCentreCTranslation

时执行此操作
INSERT into #LangCentreCTranslation (CentreId, LanguageId, CentreTranslationId,BrandIds,FeatureIds)(
SELECT 
    lc.CentreId,
    lc.LanguageId,      
    CASE WHEN ct.id IS NULL THEN ct2.id ELSE ct.id END AS CentreTranslationId,
    STUFF((SELECT ',' + convert(VARCHAR(10), brand_id) FROM dbo.CentreBrand cf WHERE cf.Centre_Id = lc.Centreid ORDER BY brand_id FOR XML PATH('')), 1, 1, '') as BrandIds,
    STUFF((SELECT ',' + convert(VARCHAR(10), feature_id) FROM dbo.CentreFeature cf WHERE cf.Centre_Id = lc.Centreid ORDER BY feature_id FOR XML PATH('')), 1, 1, '') as FeatureIds
FROM #LangCentre lc
LEFT JOIN dbo.CentreTranslation ct ON ct.centre_id = lc.CentreId AND ct.language_id = lc.LanguageId
LEFT JOIN dbo.CentreTranslation ct2 ON ct2.centre_id = lc.CentreId and ct2.language_id = 1