Implementing search functionality with multiple optional parameters against database table

前端 未结 3 689
离开以前
离开以前 2021-01-02 12:54

I would like to check if there is a preferred design pattern for implementing search functionality with multiple optional parameters against database table where the access

相关标签:
3条回答
  • 2021-01-02 13:13

    Method 1: dynamic SQL can take parameters, its pretty trivial to do and pretty much eliminates the risk of SQL injection. The best argument against dynamic SQL is how non-trivial statements can require some complex logic to generate, although this is a non-issue too if you're using a decent ORM.

    NHiberante and LinqToSql construct dynamic SQL behind the scenes, and they aren't riddled with security holes. In my opinion, you're best considering one of these two technologies before rolling your own DAL.

    Method 2: I have personally used method two in the past with no problems. You commented on the "possible performance issue for the sql", but have you profiled? Compared execution plans? In my own experience, their has been little to no performance hit using the @param is null OR col = @param approach. Remember, if it takes you 10 hours of developer time to optimize code to save 10 microseconds a year of execution time, your net savings is still almost -10 hours.

    Method 3: Combinatorial explosion. Avoid at all costs.

    0 讨论(0)
  • 2021-01-02 13:26

    I posted this as a comment, but I realized it should probably be an answer.

    It's not good to write predicates as WHERE @Param IS NULL OR Column = @Param, because the optimizer usually considers it to be non-sargable.

    Try this experiment: Take your most populated table, and try to query just for the Primary Key field, which should be your clustered index:

    DECLARE @PrimaryKey int
    SET @PrimaryKey = 1
    
    SELECT CoveredColumn
    FROM Table
    WHERE @PrimaryKey IS NULL
    OR PrimaryKeyColumn = @PrimaryKey
    
    SELECT CoveredColumn
    FROM Table
    WHERE PrimaryKeyColumn >= ISNULL(@PrimaryKey, 0)
    AND PrimaryKeyColumn <= ISNULL(@PrimaryKey, 2147483647)
    

    Both of these SELECT statements will produce identical results, assuming that the PK column is a non-negative int. But pull up the execution plan for this and you'll see a huge difference in cost. The first SELECT does a full index scan and typically takes up about 90% of the query cost.

    When you want to have optional search conditions in SQL, and you can't use dynamic SQL, it's best for performance if you can turn it into a range query instead using ISNULL. Even if the range is huge (literally half the range of an int here), the optimizer will still figure it out when the optional parameter is used.

    0 讨论(0)
  • 2021-01-02 13:30

    The Query Object pattern.

    0 讨论(0)
提交回复
热议问题