dotnet / dotnet/efcore

Some StartsWith scenarios are non-SARGable when they perhaps could be? Was it considered before?

Open
#35,691 1 comment 0 reactions 0 assignees View on GitHub
area-perf area-query customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

### Question

As an idle curio I'm trying to find efficient ways of querying for rows where "column x starts with any of collection y"

As a first try I did:

```
string[] prefixes = ["abc","defg","ghijkl"];
db.SomeTable.Where(r => prefixes.Any(p => r.SomeIndexedColumn.StartsWith(p)))
```

The generated SQL was like:

```
DECLARE @prefixes VARCHAR(100) = ' ["abc","defg","ghijkl"]';
SELECT *
FROM SomeTable t
WHERE EXISTS (
SELECT 1
FROM OPENJSON(@prefixes) WITH (p nvarchar(16) '$') AS j
WHERE
t.SomeIndexedColumn IS NOT NULL AND
j.p IS NOT NULL AND
LEFT(t.SomeIndexedColumn, LEN(j.p)) = j.p
```

Use of the LEFT clobbers SQLS ability to seek the index, but a simpler form does use and index seek rather than scan, for my DB:

```
SELECT * FROM SomeTable t
WHERE
t.SomeIndexedColumn LIKE 'abc%' OR t.SomeIndexedColumn LIKE 'defg%' OR t.SomeIndexedColumn LIKE 'ghijkl%'
```

I'm interested to know if an approach like this was ever considered by EF team as a perf optimisation - e.g. if there is some low number of items in the collection, rather than the json approach, expanding the collection directly into a set of predicates, or unions etc. Does it make sense to have EF do this for the dev, or should the devs be mindful of the effects of querying in "any startswith x" mode, and find their own strategies?

### Your code

```csharp

```

### Stack traces

```text

```

### Verbose output

```text

```

### EF Core version

8.0.0

### Database provider

_No response_

### Target framework

_No response_

### Operating system

_No response_

### IDE

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.