Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
Bex
Aged Yak Warrior
580 Posts |
Posted - 2009-10-21 : 07:25:09
|
We have a very large database which is split across multiple tables. The tables are joined using a partitioned view. However, we are encountering performance issues around parition elimination when using parameterised queries.Other than using dynamic sql, is there a way to avoid this? Here is some sample code which mimics the issue. As you will be able to see, the query will go direct to the required tables when the value is hardcoded, yet as soon as we parameterise it, it scans ALL the table partitions:SET STATISTICS PROFILE OFFGOUSE [master]GOIF EXISTS(SELECT 1 FROM sys.databases WHERE [name] = 'Test')BEGIN DROP DATABASE Test ENDGOCREATE DATABASE TestgoUSE TestGOCREATE TABLE Test1 (ID INT)GOCREATE TABLE Test2 (ID INT)GOCREATE TABLE Test3 (ID INT)GOALTER TABLE Test1 ADD CONSTRAINT CK_Test1 CHECK (ID >=1 AND ID < 6)ALTER TABLE Test2 ADD CONSTRAINT CK_Test2 CHECK (ID >=6 AND ID < 11)ALTER TABLE Test3 ADD CONSTRAINT CK_Test3 CHECK (ID >=10 AND ID < 16)GOINSERT INTO Test1SELECT 1UNIONSELECT 2UNIONSELECT 3UNIONSELECT 4UNIONSELECT 5GOINSERT INTO Test2SELECT 6UNIONSELECT 7UNIONSELECT 8UNIONSELECT 9UNIONSELECT 10GOINSERT INTO Test3SELECT 11UNIONSELECT 12UNIONSELECT 13UNIONSELECT 14UNIONSELECT 15GO-- Check the constraint is working. This should throw an error--INSERT INTO Test3--SELECT 1GOCREATE VIEW TestPartitionASSELECT ID FROM Test1UNION ALLSELECT ID FROM Test2UNION ALLSELECT ID FROM Test3GO-- Test whether SQL Server will eliminate the irrelevant partitionsSET STATISTICS PROFILE ONGODECLARE @ID INTSET @ID = 2SELECT * FROM TestPartition WHERE ID = @IDGOSELECT * FROM TestPartition WHERE ID = 2GODECLARE @ID INTSET @ID = 8SELECT * FROM TestPartition WHERE ID < @IDGOSELECT * FROM TestPartition WHERE ID < 8GOSET STATISTICS PROFILE OFFGOUSE [master]GOIF EXISTS(SELECT 1 FROM sys.databases WHERE [name] = 'Test')BEGIN DROP DATABASE Test END Hearty head pats |
|
|
Bex
Aged Yak Warrior
580 Posts |
Posted - 2009-10-21 : 08:50:32
|
| Having done some reading around the subject, it appears that when the optimiser creates the query plan, it does not know the values of the parameters (since the whole point of using parameterized queries is to encourage re-use of query plans). Therefore, without knowing the values, it cannot predict which partition it will need to access, hence creating conditional logic across ALL the partitions.I have no idea what to do, as our application uses LINQ which parameterises all the queries???Hearty head pats |
 |
|
|
|
|
|