Particular SQL Query performance improving - c#

I use Amazon Lambda which has memory limits for proceeding certain actions. And this query retrieving quite a lot of data (~100k+ rows) and running out of those limits.
SELECT EE.ID, ILE.Zip AS EventLocationZip, EET.Name as EventType, EE.TypeID as EventTypeID, E.Length, EL.Name as LengthUnit,
CP.Name as EventPlaceName, EE.FKPlaceID as EventPlaceID, IL.Name as EventLocationName, IL.ID as EventLocationId,
I.ID as InstituteID, I.Name as InstituteName, I.Email, I.Telephone, I.FAX, ILA.City, ILA.Zip, ILA.Street, ILA.Country,
E.ID as EducationID, E.Name as EducationName, E.Link as EducationLink, CE.Name as EducationTypeName, CE.ID as EducationTypeID,
ESI.TypeID as EventStartInfoTypeID, ESI.Date as StartDate, ESI.EndDate, ESI.Month, ESI.MonthYear, ESI.FKSemesterID as Semester, ESI.SemesterYear,
EEP.Vat, EEP.Price, EC.Name as Currency, IP.Value as TextPropertyValue, IP.FKTextPropertyID as TextPropertyID, CPIL.Name AS EventLocationPlaceName,
CPIL2.Name AS EventLocationPlaceNameParent
FROM
education.EducationEvents EE
INNER JOIN education.EventStartInfos ESI ON EE.ID = ESI.FKEducationEventID
INNER JOIN education.EducationEventPrices EEP ON EE.ID = EEP.FKEventID
INNER JOIN education.TypeOfEvents EET ON EE.TypeID = EET.ID
LEFT JOIN institute.InstituteLocations IL ON IL.ID = EE.FKLocationID
LEFT JOIN core.Places CPIL ON CPIL.ID = IL.FKPlaceID
LEFT JOIN core.Places CPIL2 ON CPIL2.ID = CPIL.FKParentID
LEFT JOIN institute.LocationAddresses ILE ON ILE.ID = IL.FKVisitingAddressID
LEFT JOIN core.Places CP ON CP.ID = EE.FKPlaceID
INNER JOIN economy.Currencies EC ON EEP.FKCurrencyID = EC.ID
INNER JOIN education.Educations E ON EE.FKEducationID = E.ID
LEFT JOIN education.LengthUnits EL ON E.FKLengthUnitID = EL.ID
INNER JOIN core.EducationTypes CE ON CE.ID = E.FKEducationTypeID
INNER JOIN institute.Institutes I ON E.FKInstituteID = I.ID
LEFT JOIN institute.InstituteTextProperties IP ON IP.FKInstituteID = I.ID
INNER JOIN institute.LocationAddresses ILA ON ILA.ID = I.FKMainAddressID
INNER JOIN searchIndex.IndexInstitutes II ON I.ID = II.FKInstituteID
INNER JOIN searchIndex.IndexEducations IE ON E.ID = IE.FKEducationID AND II.FKIndexID = IE.FKIndexID
WHERE
II.FKIndexID = #IndexID AND I.IsPublished = 1 AND ESI.Description IS NULL AND (IP.FKTextPropertyID = 1 OR IP.FKTextPropertyID IS NULL)
ORDER BY I.ID DESC
Using Entity framework. Extension:
public static class DbContextExtensions
{
public static async Task<IReadOnlyList<T>> FromSql<T>(this DbContext context, string sql, params object[] parameters) where T : class
{
return await context.Set<T>().FromSql(sql, parameters).AsNoTracking().ToListAsync().ConfigureAwait(false);
}
}
And usage:
var data = await _context.FromSql<Model>("Query string", parameter);
What would be the best permanent solution for optimizing particular query? Thank you for the answers

Related

Multiple Left OUTER OUTER joins in LINQ to Entities

Using Linq To Entities how would I reproduce the following SQL Query?
SELECT m.MaterialId, m.MaterialName, m.MaterialTitle, vv.NearestTXDate, c.ChannelName
FROM GB_Material m
LEFT OUTER JOIN WF_VideoVersion vv on vv.MaterialID = m.MaterialID
LEFT OUTER JOIN SP_ScheduleEvent se on se.MaterialName = m.MaterialName
INNER JOIN SP_Schedule s on s.ScheduleID = se.ScheduleID
INNER JOIN GB_Channel c on c.ChannelID = s.ChannelID
WHERE LOWER(m.MaterialName) like '%foo%' OR LOWER(m.MaterialTitle) like '%foo%'
EDIT: I've excepted an answer to this as the answer produces the exact results that this SQL Query does, but be aware that the original SQL query produces an unwanted Cross Join, which i didn't realise when i wrote it.
(from m in context.GB_Material
join vv in context.WF_VideoVersion on new {m.MaterialID }
equals new { vv.MaterialID } into vv_join
from vv in vv_join.DefaultIfEmpty()
join se in context.SP_ScheduleEvent on new {m.MaterialName }
equals new { se.MaterialName } into se_join
from se in se_join.DefaultIfEmpty()
join s in context.SP_Schedule on new {se.ScheduleID } equals new { s.ScheduleID}
join c in context.GB_Channel on new { s.ChannelID } equals new { c.ChannelID }
where
m.MaterialName.ToLower().Contains("foo") || m.MaterialTitle.ToLower() .Contains("foo")
select new
{
m.MaterialId, m.MaterialName, m.MaterialTitle, vv.NearestTXDate, c.ChannelName
})
Try this query
var objlist =(from m in Contex.GB_Material
from vv in Contex.WF_VideoVersion.Where(x=>x.MaterialID =m.MaterialID ).DefaultIfEmpty()
from se in Contex.SP_ScheduleEvent.Where(x=>x.MaterialName =m.MaterialName ).DefaultIfEmpty()
from s in Contex.SP_Schedule .Where(x=>x.ScheduleID =se.ScheduleID)
from c in Contex.GB_Channel .Where(x=>x.ChannelID =s.ChannelID )
WHERE m.MaterialName.ToLower().Contains("foo") || m.MaterialTitle.ToLower() .Contains("foo")
select new{ m.MaterialId, m.MaterialName, m.MaterialTitle, vv.NearestTXDate, c.ChannelName}).ToList();

SQL query to linq with right and left joins and nested query

My sql query is
SELECT DISTINCT
tblProjects.RevID, tblProjects.CEQRNum, tblProjects.ProjectName, GEOCODE.BBL, tblProjects.BoroID, GEOCODE.BLOCK, GEOCODE.LOT,
tblMilestoneType.MilestoneName, tblMilestone.MilestoneDate
FROM tblMilestoneType INNER JOIN
tblMilestone ON tblMilestoneType.MilestoneID = tblMilestone.MilestoneTypeID RIGHT OUTER JOIN
tblProjects ON tblMilestone.RevID = tblProjects.RevID LEFT OUTER JOIN
GEOCODE ON tblProjects.RevID = GEOCODE.RevID
WHERE (
tblMilestone.MilestoneDate IN (SELECT MAX(tblMilestone.MilestoneDate) AS MilestoneDate
FROM tblMilestone INNER JOIN tblMilestoneType ON tblMilestone.MilestoneTypeID = tblMilestoneType.MilestoneID
GROUP BY tblMilestone.RevID)
)
ORDER BY tblProjects.RevID
I am trying to convert this to linq.
So i started with
projectList = db.tblMilestoneTypes
.Join(db.tblMilestones,
mileType => mileType.MilestoneID,
mile => mile.MilestoneTypeID,
(mileType, mile) => new
{
tblMilestoneType = mileType,
tblMilestone = mile
})
.Join(db.tblProjects,
project => project. // does not work)
Also tried
projectList = from MilestoneTypeTable in db.tblMilestoneTypes
join MilestoneTable in db.tblMilestones on MilestoneTypeTable.MilestoneID equals MilestoneTable.MilestoneTypeID
rig // no right or left join.
How do i do this
Neha
You can try
projectList = from MilestoneTypeTable in db.tblMilestoneTypes
join MilestoneTable in db.tblMilestones on MilestoneTypeTable.MilestoneID equals MilestoneTable.MilestoneTypeID into MileStones
from mileStone in MileStones
join from projects in db.tblProjects
on mileStone.RevID equals projects.RevID
select new { MileStoneType = MilestoneTypeTable, MileStones = mileStone , Project = projects };
Well After a lot of R&D This is what I found out
the T-SQL with LEFT OUTER JOIN and RIGHT OUTER JOIN can be converted to one query with only LEFT OUTER JOIN
put subquery as a part of join
and here is the query.
var query = from ProjectTable in db.tblProjects
from GeoCodeTable in db.GEOCODEs.Where(geo => geo.RevID == ProjectTable.RevID).DefaultIfEmpty()
from MilestoneTable in db.tblMilestones.Where(mile => mile.RevID == GeoCodeTable.RevID && mile.MilestoneDate == db.tblMilestones.OrderBy(x => x.RevID).Select(x => x.MilestoneDate).Max()).DefaultIfEmpty()
from MilestomeTypeTable in db.tblMilestoneTypes.Where(mt => mt.MilestoneID == MilestoneTable.MilestoneTypeID).DefaultIfEmpty()
select new
{
Milestone = MilestoneTable,
Project = ProjectTable,
GeoCode = GeoCodeTable,
MilestomeType = MilestomeTypeTable
};

How to two joins in linq

I trying to write sql query to linq:
Query:
select s.s_name, sub.state, sub.to, sub.evaluation, sub.task_id
from submit_task sub
join student s on s.id=sub.student_id
join task t on t.id=sub.task_id
where t.t_name = "bbbb";
Linq:
var subTask = (from sub in ado.submit_task
join s in ado.student on sub.student_id equals s.id
join t in ado.task on sub.task_id equals t.id
where t.t_name == listView3.SelectedItems[0].Text
select new { s.s_name, sub.state, sub.to,
sub.evaluation, sub.task_id });
but this not working. When I try dubugg, nothing's happened, with no error or result. Do you see some mistake ??
thankk you
var text = listView3.SelectedItems[0].Text;
var subTask = (from sub in ado.submit_task
join s in ado.student on sub.student_id equals s.id
join t in ado.task on sub.task_id equals t.id
where t.t_name == text
select new { s.s_name, sub.state, sub.to, sub.evaluation, sub.task_id });

Converting SQL to LINQ with INNER JOIN()?

I am struggling with how to write the below equivalent as LINQ. Truly I guess I am only struggling with how I represent the INNER JOIN () portion. Is that called a Nested Join? Anonymous Join? I am not even sure. Anyway, big thanks to anyone who can point me true. Even if it is just what this is called so I can BING it properly.
SELECT p.PersonID, p.FirstName, p.MiddleName, p.LastName, cp.EnrollmentID, cp.EnrollmentDate, cp.DisenrollmentDate
FROM vwPersonInfo AS p
INNER JOIN (
SELECT c.ClientID, c.EnrollmentID, c.EnrollmentDate, c.DisenrollmentDate
FROM tblCMOEnrollment AS c
LEFT OUTER JOIN tblWorkerHistory AS wh
ON c.EnrollmentID = wh.EnrollmentID
INNER JOIN tblStaffExtended AS se
ON wh.Worker = se.StaffID
WHERE (wh.EndDate IS NULL OR wh.EndDate >= getdate())
AND wh.Worker = --WorkerID Param Here
) AS cp
ON p.PersonID = cp.ClientID
ORDER BY p.PersonID
just put the inner query in its own variable. (It will be translated into one single SQL expression)
var innerQuery = from x in db.tblCMOEnrollment
where ...
select ...;
var query = from a in vwPersonInfo
join b innerQuery on p.PersonID equals cp.ClientID
select ...;
I think you can do this by writing a second method and joining on that method:
private static IEnumerable<Table> GetData(int joinKey)
{
return (from x in context.TableB.Where(id => id.Key == joinKey select x).AsQueryable();
}
Then you can do your normal query:
var query = from c in context.TableA
join GetData(c.PrimaryKeyValue)

Convert SQL query to LINQ

I have a beginners LINQ2SQL question. I have this huge (but not complex) SQL statement:
SELECT Artikel.ArtikelID,
Artikel.CategorieID,
Artikel.ImageFile,
Artikel.RetailPrijs,
ISNULL(ShopArtikel.VerkoopsPrijs, Artikel.VerkoopsPrijs) AS VerkoopsPrijs,
Artikel.ArtikelCode,
Artikel.InAssortimentSinds,
ArtikelTaal.ArtikelNaam,
ArtikelTaal.ArtikelOmschrijving
FROM Artikel
INNER JOIN ArtikelTaal ON Artikel.ArtikelID = ArtikelTaal.ArtikelID
INNER JOIN ShopArtikel ON Artikel.ArtikelID = ShopArtikel.ArtikelID
INNER JOIN Categorie ON Artikel.CategorieID = Categorie.CategorieID
INNER JOIN CategorieTaal ON Categorie.CategorieID = CategorieTaal.CategorieID
INNER JOIN Shop ON ShopArtikel.ShopId = Shop.ShopID
INNER JOIN CategorieGroepShop ON Shop.ShopID = CategorieGroepShop.ShopId
INNER JOIN Taal ON ArtikelTaal.TaalCode = Taal.TaalCode AND CategorieTaal.TaalCode = Taal.TaalCode
INNER JOIN CategorieGroepTaal ON Taal.TaalCode = CategorieGroepTaal.TaalCode AND CategorieGroepShop.CategorieGroepId = CategorieGroepTaal.CategorieGroepID
INNER JOIN CategorieGroep ON Categorie.CategorieGroepID = CategorieGroep.CategorieGroepID AND CategorieGroepTaal.CategorieGroepID = CategorieGroep.CategorieGroepID AND CategorieGroepShop.CategorieGroepId = CategorieGroep.CategorieGroepID
WHERE (Shop.ShopID = 23) AND
(Taal.TaalCode = 'dut') AND
(Artikel.Onzichtbaar = 0) AND
(Artikel.NietBestelbaar = 0) AND
(Categorie.Onzichtbaar = 0) AND
(Artikel.Voorraad >= Artikel.LevertijdDrempel)
and I am converting this to LINQ and have this:
var allProducts = from artikelen in dc.Artikels
join sa in dc.ShopArtikels on artikelen.ArtikelID equals sa.ArtikelID
join at in dc.ArtikelTaals on artikelen.ArtikelID equals at.ArtikelID
join cat in dc.Categories on artikelen.CategorieID equals cat.CategorieID
join catt in dc.CategorieTaals on cat.CategorieID equals catt.CategorieID
join catg in dc.CategorieGroeps on cat.CategorieGroepID equals catg.CategorieGroepID
join catgt in dc.CategorieGroepTaals on catg.CategorieGroepID equals catgt.CategorieGroepID
join sh in dc.Shops on sa.ShopId equals sh.ShopID
join catgs in dc.CategorieGroepShops on sh.ShopID equals catgs.ShopId
join tl in dc.Taals on new { tc1 = at.TaalCode, tc2 = catgt.TaalCode } equals new { tc1 = tl.TaalCode, tc2 = tl.TaalCode }
where sh.ShopID == shop.BLL.Business.ShopController.CurrentShop.Id
select dc.Artikels;
but I have the idea that I made some (minor) mistakes while joining.
any ideas please!
EDIT
I have rewritten the LINQ query to this:
var allProducts = from artikelen in dc.Artikels
join at in dc.ArtikelTaals on artikelen.ArtikelID equals at.ArtikelID
join sa in dc.ShopArtikels on artikelen.ArtikelID equals sa.ArtikelID
join cat in dc.Categories on artikelen.CategorieID equals cat.CategorieID
join catt in dc.CategorieTaals on cat.CategorieID equals catt.CategorieID
join sh in dc.Shops on sa.ShopId equals sh.ShopID
join catgs in dc.CategorieGroepShops on sh.ShopID equals catgs.ShopId
join tl in dc.Taals on new { tc1 = at.TaalCode, tc2 = catt.TaalCode } equals new { tc1 = tl.TaalCode, tc2 = tl.TaalCode }
join catgt in dc.CategorieGroepTaals on new { tl.TaalCode, catgs.CategorieGroepId } equals new { catgt.TaalCode, catgt.CategorieGroepID }
join catg in dc.CategorieGroeps on new { cat.CategorieGroepID, catgt.CategorieGroepID, catgs.CategorieGroepId } equals new { catg.CategorieGroepID, catg.CategorieGroepID, catg.CategorieGroepID }
where sh.ShopID == 230
select dc.Artikels;
but I have a syntax error after "dut" }
Edit 2:
changed the join and replaced "dut" with the corresponding field in the database.
still have the error after the first }
it says: type inference failed in the call to 'Join'
Some of the SQL joins have multiple join conditions, which you didn't put in the LINQ query.
If this is something that will be frequently run then you should rewrite it as a stored procedure. I believe it is too convoluted and complex for a LINQ statement - too hard to see what's going on.
There is a tool for it, but I didn't try it. May be it's usefull for you.
http://www.sqltolinq.com/
It looks like the error line is actually a "Where" cause but not "Joining".
You can actually split the whole long Linq statement into smaller Query.
so for this case, its better to split it like this:
var at = from a in dc.ArtikelTaals
where a.TaalCode == "dut"
select a;
var catt = from c in dc.CategorieTaals
where c.TaalCode == "dut"
select c;
.....
and you can join the IQueryable "at" and "catt" in your complex query later.

Categories

Resources