While we wait for you to add more pertinent and important details to your question, I propose some concrete suggestions.
Solve problems due to the use of a variable of type table
with many records
It happens that I get a total of 145,000 data in @Temp_Entidades
Using @Temp_Entidades
with so much data in your second query can definitely cause you performance problems, for at least 2 potential reasons:
Your second query would probably find a better execution plan if @Temp_Entidades
had an index for the column Id
, but does not have it.
One way to define an index in the case of a variable of type table
, as it is @Temp_Entidades
, is to define it implicitly by means of a primary key:
DECLARE @Temp_Entidades TABLE(Id int primary key);
Another very serious problem is that when a variable of type table
is used in a query, by default SQL Server does not have statistics regarding that table. Rather, SQL Server simply assumes that the table (in this case @Temp_Entidades
) only has one record (you can verify this by examining your current execution plan). This, in turn, can lead you to choose a completely wrong execution plan for the query, since the table actually has 145,000 records, not just one.
For SQL Server to access statistics for @Temp_Entidades
, you have 2 options:
Use a temporary table instead of a variable of type table
:
create table #Temp_Entidades (Id int primary key);
Or add the suggestion option (recompile)
to the query:
select distinct p.Nombres
from Personas as p
inner join Estados as e on p.EstadoId=e.Id
inner join EntidadesPersonas as ep on p.Id=ep.PersonaId
where ep.EntidadId in (select Id from @Temp_Entidades)
and p.EstadoId<>69
option (recompile) -- agregar aquí
Review indexes
Of course, you may have to check if you have the right indexes in the other tables. It is difficult to give you correct recommendations without 100% clear the relationship between the tables and the number of records in each. But, from what I can deduce, it makes sense to define the following indices:
-
Estados (Id)
-
Personas (Id)
-
EntidadesPersonas (EntidadId)
-
EntidadesPersonas (PersonaId)
-
@Temp_Entidades (Id)
Formulate the query differently
Personally, I would formulate the query a bit differently, for example, using exists
instead of in
. But in practice, I doubt that something changes, since, in general, SQL Server has the intelligence necessary to make those kinds of modifications automatically if you see it beneficial.
But just in case, here is the query as I would formulate it in this case:
select distinct p.Nombres
from Personas p
join Estados e
on e.Id = p.EstadoId
join EntidadesPersonas ep
on ep.PersonaId = p.Id
and exists(select null
from @Temp_Entidades te
where te.Id = ep.EntidadId)
where p.EstadoId <> 69
option (recompile)
Delete intermediary results between queries
Again, it is obvious that important details are missing in your question. For example, where does @Temp_Prom
come from?
But, from what I can see, I get the impression that a single SQL query would have been enough to get the desired final results. But you have divided it into at least 3 smaller queries using variables of type table
to load the temporary results of each query and pass it to the next one. Why? Was it about trying to improve performance?
In my opinion, it would be worth examining if you can not improve performance by combining the different queries. As long as you have the right indexes defined, I suspect that is the best option. But to help you with this, you need to add the missing details to your question.