Spring data JPA with SQL Server - lower() function causes full table scan










0















In a simple SpringBoot (2.0.5) + JPA + SQL Server microservice with persistence via a JpaRepository implementation (no additional methods), we are seeing the transact-sql lower() function being injected into the generated SQL wrapping the queried column(s), which in turn causes a full table scan and therefore impacts performance on what would otherwise be a simple, fast index-supported query.



Clearly this is to make the queries case-insensitive, however as SQL Server is case-insensitive by default there is no need for this function to be injected. I can see from the Spring Data JPA docs that suffixing repository methods with IgnoreCase should make queries case-insensitive for DBs that are case-sensitive by default, however I can't see how to configure it to respect the incoming case..



JPA config:



jpa:
show-sql: true
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
dialect: org.hibernate.dialect.SQLServer2012Dialect
ddl-auto: validate


Repository interface:



@Repository
public interface MyRepo extends JpaRepository<Thing, Long>, QuerydslPredicateExecutor<Thing>


I have tried removing the SQLServer2012Dialect from the config - no difference. I am unsure if the additional use of QueryDSL might be having an impact - I shall try temporarily removing that (although it is required).










share|improve this question
























  • Which method are you calling on MyRepo? And I would also say that Querydsl is the problem. I've never seen that hibernate is adding any lower or upper function without telling so

    – Simon Martinelli
    Nov 13 '18 at 12:34











  • I think you may be right, I'm going to try removing it this afternoon. This is the method I'm calling (which is indeed from QuerydslPredicateExecutor: Page<T> findAll(Predicate predicate, Pageable pageable);

    – Tom Bunting
    Nov 13 '18 at 13:18











  • and how does the predict look like?

    – Simon Martinelli
    Nov 13 '18 at 13:23











  • that was it - see answer ;-)

    – Tom Bunting
    Nov 13 '18 at 13:29















0















In a simple SpringBoot (2.0.5) + JPA + SQL Server microservice with persistence via a JpaRepository implementation (no additional methods), we are seeing the transact-sql lower() function being injected into the generated SQL wrapping the queried column(s), which in turn causes a full table scan and therefore impacts performance on what would otherwise be a simple, fast index-supported query.



Clearly this is to make the queries case-insensitive, however as SQL Server is case-insensitive by default there is no need for this function to be injected. I can see from the Spring Data JPA docs that suffixing repository methods with IgnoreCase should make queries case-insensitive for DBs that are case-sensitive by default, however I can't see how to configure it to respect the incoming case..



JPA config:



jpa:
show-sql: true
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
dialect: org.hibernate.dialect.SQLServer2012Dialect
ddl-auto: validate


Repository interface:



@Repository
public interface MyRepo extends JpaRepository<Thing, Long>, QuerydslPredicateExecutor<Thing>


I have tried removing the SQLServer2012Dialect from the config - no difference. I am unsure if the additional use of QueryDSL might be having an impact - I shall try temporarily removing that (although it is required).










share|improve this question
























  • Which method are you calling on MyRepo? And I would also say that Querydsl is the problem. I've never seen that hibernate is adding any lower or upper function without telling so

    – Simon Martinelli
    Nov 13 '18 at 12:34











  • I think you may be right, I'm going to try removing it this afternoon. This is the method I'm calling (which is indeed from QuerydslPredicateExecutor: Page<T> findAll(Predicate predicate, Pageable pageable);

    – Tom Bunting
    Nov 13 '18 at 13:18











  • and how does the predict look like?

    – Simon Martinelli
    Nov 13 '18 at 13:23











  • that was it - see answer ;-)

    – Tom Bunting
    Nov 13 '18 at 13:29













0












0








0








In a simple SpringBoot (2.0.5) + JPA + SQL Server microservice with persistence via a JpaRepository implementation (no additional methods), we are seeing the transact-sql lower() function being injected into the generated SQL wrapping the queried column(s), which in turn causes a full table scan and therefore impacts performance on what would otherwise be a simple, fast index-supported query.



Clearly this is to make the queries case-insensitive, however as SQL Server is case-insensitive by default there is no need for this function to be injected. I can see from the Spring Data JPA docs that suffixing repository methods with IgnoreCase should make queries case-insensitive for DBs that are case-sensitive by default, however I can't see how to configure it to respect the incoming case..



JPA config:



jpa:
show-sql: true
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
dialect: org.hibernate.dialect.SQLServer2012Dialect
ddl-auto: validate


Repository interface:



@Repository
public interface MyRepo extends JpaRepository<Thing, Long>, QuerydslPredicateExecutor<Thing>


I have tried removing the SQLServer2012Dialect from the config - no difference. I am unsure if the additional use of QueryDSL might be having an impact - I shall try temporarily removing that (although it is required).










share|improve this question
















In a simple SpringBoot (2.0.5) + JPA + SQL Server microservice with persistence via a JpaRepository implementation (no additional methods), we are seeing the transact-sql lower() function being injected into the generated SQL wrapping the queried column(s), which in turn causes a full table scan and therefore impacts performance on what would otherwise be a simple, fast index-supported query.



Clearly this is to make the queries case-insensitive, however as SQL Server is case-insensitive by default there is no need for this function to be injected. I can see from the Spring Data JPA docs that suffixing repository methods with IgnoreCase should make queries case-insensitive for DBs that are case-sensitive by default, however I can't see how to configure it to respect the incoming case..



JPA config:



jpa:
show-sql: true
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
dialect: org.hibernate.dialect.SQLServer2012Dialect
ddl-auto: validate


Repository interface:



@Repository
public interface MyRepo extends JpaRepository<Thing, Long>, QuerydslPredicateExecutor<Thing>


I have tried removing the SQLServer2012Dialect from the config - no difference. I am unsure if the additional use of QueryDSL might be having an impact - I shall try temporarily removing that (although it is required).







java sql-server hibernate spring-data-jpa querydsl






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 13:31







Tom Bunting

















asked Nov 13 '18 at 12:11









Tom BuntingTom Bunting

1,069717




1,069717












  • Which method are you calling on MyRepo? And I would also say that Querydsl is the problem. I've never seen that hibernate is adding any lower or upper function without telling so

    – Simon Martinelli
    Nov 13 '18 at 12:34











  • I think you may be right, I'm going to try removing it this afternoon. This is the method I'm calling (which is indeed from QuerydslPredicateExecutor: Page<T> findAll(Predicate predicate, Pageable pageable);

    – Tom Bunting
    Nov 13 '18 at 13:18











  • and how does the predict look like?

    – Simon Martinelli
    Nov 13 '18 at 13:23











  • that was it - see answer ;-)

    – Tom Bunting
    Nov 13 '18 at 13:29

















  • Which method are you calling on MyRepo? And I would also say that Querydsl is the problem. I've never seen that hibernate is adding any lower or upper function without telling so

    – Simon Martinelli
    Nov 13 '18 at 12:34











  • I think you may be right, I'm going to try removing it this afternoon. This is the method I'm calling (which is indeed from QuerydslPredicateExecutor: Page<T> findAll(Predicate predicate, Pageable pageable);

    – Tom Bunting
    Nov 13 '18 at 13:18











  • and how does the predict look like?

    – Simon Martinelli
    Nov 13 '18 at 13:23











  • that was it - see answer ;-)

    – Tom Bunting
    Nov 13 '18 at 13:29
















Which method are you calling on MyRepo? And I would also say that Querydsl is the problem. I've never seen that hibernate is adding any lower or upper function without telling so

– Simon Martinelli
Nov 13 '18 at 12:34





Which method are you calling on MyRepo? And I would also say that Querydsl is the problem. I've never seen that hibernate is adding any lower or upper function without telling so

– Simon Martinelli
Nov 13 '18 at 12:34













I think you may be right, I'm going to try removing it this afternoon. This is the method I'm calling (which is indeed from QuerydslPredicateExecutor: Page<T> findAll(Predicate predicate, Pageable pageable);

– Tom Bunting
Nov 13 '18 at 13:18





I think you may be right, I'm going to try removing it this afternoon. This is the method I'm calling (which is indeed from QuerydslPredicateExecutor: Page<T> findAll(Predicate predicate, Pageable pageable);

– Tom Bunting
Nov 13 '18 at 13:18













and how does the predict look like?

– Simon Martinelli
Nov 13 '18 at 13:23





and how does the predict look like?

– Simon Martinelli
Nov 13 '18 at 13:23













that was it - see answer ;-)

– Tom Bunting
Nov 13 '18 at 13:29





that was it - see answer ;-)

– Tom Bunting
Nov 13 '18 at 13:29












1 Answer
1






active

oldest

votes


















0














On closer inspection of the QueryDsl predicate, this was straightforward (and self-inflicted) - changed the use of equalsIgnoreCase() in the predicate to eq() and that has resolved the issue. So no issue in config or libraries, but one to be aware of.






share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53280766%2fspring-data-jpa-with-sql-server-lower-function-causes-full-table-scan%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    On closer inspection of the QueryDsl predicate, this was straightforward (and self-inflicted) - changed the use of equalsIgnoreCase() in the predicate to eq() and that has resolved the issue. So no issue in config or libraries, but one to be aware of.






    share|improve this answer



























      0














      On closer inspection of the QueryDsl predicate, this was straightforward (and self-inflicted) - changed the use of equalsIgnoreCase() in the predicate to eq() and that has resolved the issue. So no issue in config or libraries, but one to be aware of.






      share|improve this answer

























        0












        0








        0







        On closer inspection of the QueryDsl predicate, this was straightforward (and self-inflicted) - changed the use of equalsIgnoreCase() in the predicate to eq() and that has resolved the issue. So no issue in config or libraries, but one to be aware of.






        share|improve this answer













        On closer inspection of the QueryDsl predicate, this was straightforward (and self-inflicted) - changed the use of equalsIgnoreCase() in the predicate to eq() and that has resolved the issue. So no issue in config or libraries, but one to be aware of.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 13 '18 at 13:28









        Tom BuntingTom Bunting

        1,069717




        1,069717





























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53280766%2fspring-data-jpa-with-sql-server-lower-function-causes-full-table-scan%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

            Syphilis

            Darth Vader #20