nhibernate / nhibernate-core

NHibernate Object Relational Mapper
https://nhibernate.info
GNU Lesser General Public License v2.1
2.13k stars 929 forks source link

If there is an unequal operator in the query, HQL Query Plan is regenerated #3069

Open cokalyoncu opened 2 years ago

cokalyoncu commented 2 years ago
CrdCardResponse crdCardResponse = Query<CrdCard>()
    .Where(x => x.CardNo == cardNo)
    .Select(x => new CrdCardResponse()
    {
        IsLimitExceed = x.Dci != CardDci.Credit.GetKey()
    }).SingleOrDefault();

Hql query plan is regenerated each time this query is run. If the query is changed in this way, hql query plan is cached.

CrdCardResponse crdCardResponse = Query<CrdCard>()
    .Where(x => x.CardNo == cardNo)
    .Select(x => new CrdCardResponse()
    {
        IsLimitExceed = x.Dci == CardDci.Credit.GetKey()
    }).SingleOrDefault();

This line in SelectClauseHqlNominator is causing this trouble:

var projectConstantsInHql = _stateStack.Peek() || expression.NodeType == ExpressionType.Equal || IsRegisteredFunction(expression);

This code should be changed like this:

var projectConstantsInHql = _stateStack.Peek() || expression.NodeType == ExpressionType.Equal || expression.NodeType == ExpressionType.NotEqual || IsRegisteredFunction(expression);
gokhanabatay commented 2 years ago

@fredericDelaporte is it ok to change as @cokalyoncu suggested it effects performance of our application and we don't know until we investigate deeply ?

var projectConstantsInHql = _stateStack.Peek() || expression.NodeType == ExpressionType.Equal || expression.NodeType == ExpressionType.NotEqual || IsRegisteredFunction(expression);
bahusoid commented 2 years ago

I don't understand importance of Equal/NotEqual operators. Shouldn't this check at least include all others comparison operators too (<, >, ...)

gokhanabatay commented 2 years ago

I don't understand importance of Equal/NotEqual operators. Shouldn't this check at least include all others comparison operators too (<, >, ...)

You are right with other operators (<, >, ...) in our case we just faced this issue with not equal operator. QueryPlanCache is effects application performance under high load.

gokhanabatay commented 2 years ago

Hi @bahusoid could you lead us for providing fix for this issue.

bahusoid commented 2 years ago

What assistance do you need? Just prepare pull request with the fix and a test case. Fix should be applied at least for all comparison operations Maybe others binary operations too - I don't understand this code.