Hakan Axheim

Hakan Axheim

  • NA
  • 201
  • 32.4k

Need help regarding performance with a complicated SQL query

Mar 26 2018 3:20 PM
Hi,
 
I need help with a complicated SQL query regarding to performance.
 
This SQL query executes in an SQLServer 2015 relational database server in a stored procedure.
One difficulty is that room_period.beginning and room_period.beginTime does not have the same datatype. Beginning is an Datetime and beginTime is CHAR(5). This is very stupid because when I concatenate this 2 columns with + it will be an implicit conversion which turns off index.
 
As you see there is a lot of logic in the select statement with case when and so on.
 
There is also a lot of logic in the where clause. We also use select distinct in this query.
 
Should we be careful with the select distinct statement?
 
Do the select distinct statement generate a table scan?
 
Regarding to performance is it better to create a cursor in the stored procedure with a SQL query that has no case when logic. All such logic will then be performed in a WHILE statement.
 
How to get rid of the implicit conversion which turns off index?
 
Unfortunately, I cannot change any datatype in the database.
 
Here comes the SQL query:
  1. select distinct room_status.col1, room_status.col2, room_status.col3, room_status.col4, room_status.col5,  
  2. -- start  
  3. case when  
  4. room_period.beginning is not null and room_period.begintime is not null  
  5. then  
  6. (room_period.beginning + room_period.begintime)  
  7. else  
  8. null  
  9. end as 'startTime',  
  10. -- end  
  11. case when  
  12. room_period.endDate is not null and room_period.endTime is not null  
  13. then  
  14. (room_period.endDate + room_period.endTime)  
  15. when  
  16. room_period.endDate is null and room_period.probable_end is not null and room_period.probable_end <= @END  
  17. then  
  18. room_period.probable_end  
  19. else  
  20. null  
  21. end as 'endTime',  
  22. case  
  23. --- busy-unavailable  
  24. when  
  25. (room_status.col4='inactive' or room_status.col4='suspended')  
  26. or not (  
  27. (@START >= rooms.robeginning)  
  28. and  
  29. (rooms.roend is null or @END <= rooms.roend)  
  30. )  
  31. then 'busy-unavailable'  
  32. --- busy  
  33. when (  
  34. (  
  35. (room_period.endDate is not null and room_period.endTime is not null and (room_period.endDate + room_period.endTime) >= @START )  
  36. or  
  37. (room_period.probable_end is not null and room_period.probable_end >= @START)  
  38. or  
  39. ((room_period.beginning + room_period.begintime) >= @START and (room_period.beginning + room_period.begintime) <= @END )  
  40. or  
  41. ((room_period.endDate is null or room_period.endTime is nulland (room_period.beginning + room_period.begintime) <= @END)  
  42. or  
  43. (room_period.probable_end is null and (room_period.beginning + room_period.begintime) <= @END)  
  44. )  
  45. and  
  46. room_status.col4 = 'active'  
  47. )  
  48. then 'busy'  
  49. else 'unknown' end as freeBusy,  
  50. room_period.person_id,  
  51. room_period.probable_end  
  52. from table1 as rooms, table2 as room_period, table3 as room_status  
  53. where rooms.roidnr=room_status.col2  
  54. and rooms.roward=room_status.col1  
  55. and room_period.wpward = room_status.col1  
  56. and room_period.wproom = room_status.col2  
  57. and room_period.wpbed = room_status.col3  
  58. and room_period.wpstatus = '1'  
  59. and (  
  60. ((room_period.endDate is null or room_period.endTime is nulland @END > (room_period.beginning + room_period.begintime))  
  61. or  
  62. ((room_period.endDate is not null and room_period.endTime is not nulland @START < (room_period.endDate + room_period.endTime) and @END > (room_period.beginning + room_period.begintime))  
  63. or  
  64. ((room_period.endDate is null or room_period.endTime is nulland room_period.probable_end is not null and @START <= room_period.probable_end and @END >= (room_period.beginning + room_period.begintime))  
  65. or  
  66. ((room_period.endDate is not null and room_period.endTime is not nulland room_period.probable_end is not null  
  67. and @START < (room_period.endDate + room_period.endTime) and @START <= room_period.probable_end and @END >= (room_period.beginning + room_period.begintime))  
  68. )

Answers (2)