Linq2db: Introduce (Oracle) optimizer hints (on select )

Created on 2 Jul 2019  路  5Comments  路  Source: linq2db/linq2db

Oracle allows adding optimizer hint comments on selects that influence the execution plan of the query. With linq2db we can only add queryhints that get appended to the query but don't help in case of an Oracle DB.
I'd like to propose a feature that would look like this.

var result = db.TableName
   .Where(foo => foo.bar = "baz")
   .SelectWithHint("/* +NO_INDEX(TableName_bar) */", foo => foo.bar ).ToList();

this would create SQL like that:

SELECT /* +NO_INDEX(TableName_bar) */ bar  FROM foo WHERE bar = "baz";

Right now i don't see that this is possible. In case of an convoluted legacy DB this Oracle feature is essential.
Here are some more infos to Oracle query hints: https://docs.oracle.com/cd/B12037_01/server.101/b10752/hintsref.htm

feature

Most helpful comment

Yes, this is definitely one of features we want to implement.
It will need some research to gather information about hints in all databases we support, to design and implement proper API, so it will take some time.
I will add it to 3.0 roadmap

All 5 comments

Yes, this is definitely one of features we want to implement.
It will need some research to gather information about hints in all databases we support, to design and implement proper API, so it will take some time.
I will add it to 3.0 roadmap

I'd like to emphasize that this feature is mandatory to change the optimizer behavior.
See The undocumented Oracle SQL materialize Hint

Hi @sdanyliv, do you know if there is a way to change the SQL generated by linq2db just before sending the query to the DB? I need a way to insert an hint to some select and I'd like to do it using regular expressions without waiting for the next linq2db release if possible.

Try to override ExecuteReader and ExecuteReaderAsync in DataConnection and correct CommandText.

Thank you @sdanyliv for your suggestion. I'd like to share my code if someone else need to change the SQL used by DataConnection:
``` C#
using System.Data;
using System.Data.Common;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

namespace DataModels.Wip
{
public partial class WipDB : LinqToDB.Data.DataConnection
{
protected override IDataReader ExecuteReader(IDbCommand command, CommandBehavior commandBehavior)
{
command.CommandText = Regex.Replace(command.CommandText, @"GetActivityLogStartBySfcs(\s)?((\s|.)?SELECT", "$0 /*+ materialize */");
return base.ExecuteReader(command, commandBehavior);
}

    protected override Task<DbDataReader> ExecuteReaderAsync(IDbCommand command, CommandBehavior commandBehavior, CancellationToken cancellationToken)
    {
        command.CommandText = Regex.Replace(command.CommandText, @"GetActivityLogStartBySfcs(\s)*?\((\s|.)*?SELECT", "$0 /*+ materialize */");
        return base.ExecuteReaderAsync(command, commandBehavior, cancellationToken);
    }
}

}
```
GetActivityLogStartBySfcs is the name of the Cte that I need to modify adding the /*+ materialize */ hint.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jogibear9988 picture jogibear9988  路  5Comments

a-karpov-parc picture a-karpov-parc  路  4Comments

CrazyAlex25 picture CrazyAlex25  路  5Comments

bofagah400 picture bofagah400  路  4Comments

SergeyA picture SergeyA  路  4Comments