NHibernate inconsistent sql column alias - sql

When looking at our queries from NHibernate it's clear that the column alias is not consistent, that a problem for performance when the sql server execution plan seeing the same query as different query's because of the inconsistent column alias.
An example could be something like this:
SELECT this_.Id as Id44_0_ FROM dbo.[Foos] this_
SELECT this_.Id as Id43_0_ FROM dbo.[Foos] this_
Is there any way we can make consistent column alias?
We are using Fluent NHibernate with Auto mapping

Optionally by setting projection you can get a custom name as an alias in the query as follows
Projections.Property("candidate.Name"), "CandidateName");
How to use NHibernate Projections to retrieve a collection

I never seen same NH query to generate different SQL while your application is running.
I think you don't need to worry about performance because of this. (Except of the case when you need to start and stop you app frequently.)
Any changes you need to make SQL queries consistent all the time (even after you data model changes) are painful, not absolutely good solutions and I think not acceptable for you.

Related

Rails - find_by_sql vs active record querying

I would like to use the find_by_sql method in place of the active record query interface because of the flexibility I get in writing my own SQL.
For example,
It is considered a good practice in SQL to order the tables in your query from smallest to largest. When using the active record query interface, you will have to start with the result model which could be the largest table.
I can also easily avoid the N+1 problem by including the target table in the join itself and including the required columns from multiple tables.
I would like to know if there are reasons I should not be using the find_by_sql option, especially when I will be writing ANSI SQL that should be compatible with all, if not most databases.
Thanks!
Writing SQL code directly is normally not encouraged because it will prevent you from accessing features such as the lazy-execution of SQL queries and may potentially lead to invalid or unsafe queries.
In fact, ActiveRecord automatically converts Ruby objects into corresponding SQL statements (such as ranges into BETWEEN or arrays into IN), filters strings from SQL injections and ActiveRecord::Relations provide lazy query executions.
That said, if you know what you are doing or using ActiveRecord would be extremely complex to achieve a specific query, there is nothing wrong to write your SQL.
My suggestion is to avoid doing that for queries that can easily be reproduced in ActiveRecord and AREL.

nhibernate and window functions

Is there any way to get NHibernate to use a Window function?
Specifically, I'm looking to create a query like the following:
SELECT
date,
SUM(Price) OVER (ORDER BY date)
FROM purchases
GROUP BY date
I've Search the web and can't find anything about window functions and NHibernate
Specifically, I'm using the QueryOver interface for NHibernate.
If it's not possible, what other solutions are there to keep database independence in my code?
Good question but unfortunately I've never seen any code within NHibernate itself that would allow it to generate such a window function.
Your only option would be to use a named query. In your named query you could either type out the SQL by hand or call a stored procedure.
You stated that you wanted to keep your solution database independent. I've never personally cared much doing such as thing as I always work with SQL Server but I can understand where you're coming from. I've heard of several people who run their integration tests with an in memory SQLite solution and then run their actual code on SQL Server or Oracle.
In your scenario, I don't believe the SQL in your question is ANSI compliant anyway so you'd have to re-write it in a different way unfortunately if you used a named query to make it database independent.
As far as I know, you can't do that with the QueryOver API.
What I would do to keep as DB independant as possible would be to consider the windowed query as a join between your table and a group by query. Then to write a QueryOver which would lead this join.
Considering you query it would lead to this : (though the example does not seem to really show the need for a windowed query)
SELECT
purchases.date,
purchasesGroup.priceSum
FROM
purchases
INNER JOIN
(SELECT date, SUM(Price) as priceSum FROM purchases GROUP BY date)
AS purchasesGroup
on purchases.date = purchasesGroup.date
You could potentially use a view for this. That could at least abstract away a little bit of it, although you are really migrating the dependency to the database schema.
I've run into this kind of issue as well lately, and I'm starting to realize that I am often trying to use NHibernate in a way that isn't really about persisting entities. If I were Ayende Rahien I would probably know what to do, but since I am not I usually end up mixing in a little Dapper when I just need something like a read-only aggregate result such as statistics about data.

NHibernate problem choosing between CreateSql and CreateCriteria

I have a very silly doubt in NHibernate. There are two or three entities of which two are related and one is not related to other two entities. I have to fetch some selected columns from these three tables by joining them. Is it a good idea to use session.CreateSql() or we have to use session.CreateCriteria(). I am really confused here as I could not write the Criteria queries here and forced to use CreateSql. Please advise.
in general you should avoid writing SQL whenever possible;
one of the advantages of using an ORM is that it's implementation-agnostic.
that means that you don't know (and don't care) what the underlying database is, and you can actually switch DB providers or tweak with the DB structure very easily.
If you write your own SQL statements you run the risk of them not working on other providers, and also you have to maintain them yourself (for example- if you change the name of the underlying column for the Id property from 'Id' to 'Employee_Id', you'd have to change your SQL query, whereas with Criteria no change would be necessary).
Having said that- there's nothing stopping you from writing a Criteria / HQL that pulls data from more than one table. for example (with HQL):
select emp.Id, dep.Name, po.Id
from Employee emp, Department dep, Posts po
where emp.Name like 'snake' //etc...
There are multiple ways to make queries with NH.
HQL, the classic way, a powerful object oriented query language. Disadvantage: appears in strings in the code (actually: there is no editor support).
Criteria, a classic way to create dynamic queries without string manipulations. Disadvantages: not as powerful as HQL and not as typesafe as its successors.
QueryOver, a successor of Criteria, which has a nicer syntax and is more type safe.
LINQ, now based on HQL, is more integrated then HQL and typesafe and generally a matter of taste.
SQL as a fallback for cases where you need something you can't get the object oriented way.
I would recommend HQL or LINQ for regular queries, QueryOver (resp. Criteria) for dynamic queries and SQL only if there isn't any other way.
To answer your specific problem, which I don't know: If all information you need for the query is available in the object oriented model, you should be able to solve it by the use of HQL.

What adavantages does HQL have over SQL for Group By queries

I am concentrating this question on 'reporting-type' queries (count, avg etc. i.e. ones that don't return the domain model itself) and I was just wondering if there is any inherent performance benefit in using HQL, as it may be able to leverage the second level cache. Or perhaps even better - cache the entire query.
The obvious implied benefit is that NHibernate knows what the column names are as it already knows about the model mapping.
Any other benefits I should be aware of?
[I am using NHibernate but I assume that in this instance what applies to Hibernate will be equally applicable to NHibernate]
There are zero advantages. HQL will not outperform a direct database query to perform data aggregation and computation.
The result of something like:
Select count(*), dept from employees group by dept
Will always perform faster at the DB then in HQL. Note I say always because it is lame to take the 'depends on your situation' line of thinking. If it has to do with data and data aggregation; do it in SQL.
The objects in the second level cache are only retrieved by id, so Hibernate will always run a query to obtain a list of ids and then read those objects either from the second-level cache or with another query.
On the other hand, Hibernate can cache the query and avoid the DB call completely in some situations. However you have to consider that a change to any of the tables involved in the query will invalidate it, so you might not hit the cache very often. See here a description of how the query-cache works.
So the cost of your query is either 0, if the query is cached, or about the same as doing the query in straight SQL. Depending on how often your data changes you might save a lot by enabling query caching or you might not save anything.
If you have a high volume of queries and you can tolerate stale results, I'd say it's a lot better to use another cache for the query results that only expires every x minutes.
The only advantage i can think of is that ORM queries are typically cached at the (prepared) statement level, so if you do the same query lots of times chances are you are reusing a prepared statement.
But since you asked specifically for reporting queries and performance, I cannot think of any practical advantages (I'm glossing over the fact that you have other advantages like data-access consistency, ORM querying vs SQL (most of the times it's easier to write a query with HQL), data-type conversions, etc )
HQL is an object query language. SQL is a relational query language.

Does the way you write sql queries affect performance?

say i have a table
Id int
Region int
Name nvarchar
select * from table1 where region = 1 and name = 'test'
select * from table1 where name = 'test' and region = 1
will there be a difference in performance?
assume no indexes
is it the same with LINQ?
Because your qualifiers are, in essence, actually the same (it doesn't matter what order the where clauses are put in), then no, there's no difference between those.
As for LINQ, you will need to know what query LINQ to SQL actually emits (you can use a SQL Profiler to find out). Sometimes the query will be the simplest query you can think of, sometimes it will be a convoluted variety of such without you realizing it, because of things like dependencies on FKs or other such constraints. LINQ also wouldn't use an * for select.
The only real way to know is to find out the SQL Server Query Execution plan of both queries. To read more on the topic, go here:
SQL Server Query Execution Plan Analysis
Should it? No. SQL is a relational algebra and the DBMS should optimize irrespective of order within the statement.
Does it? Possibly. Some DBMS' may store data in a certain order (e.g., maintain a key of some sort) despite what they've been told. But, and here's the crux: you cannot rely on it.
You may need to switch DBMS' at some point in the future. Even a later version of the same DBMS may change its behavior. The only thing you should be relying on is what's in the SQL standard.
Regarding the query given: with no indexes or primary key on the two fields in question, you should assume that you'll need a full table scan for both cases. Hence they should run at the same speed.
I don't recommend the *, because the engine should look for the table scheme before executing the query. Instead use the table fields you want to avoid unnecessary overhead.
And yes, the engine optimizes your queries, but help him :) with that.
Best Regards!
For simple queries, likely there is little or no difference, but yes indeed the way you write a query can have a huge impact on performance.
In SQL Server (performance issues are very database specific), a correlated subquery will usually have poor performance compared to doing the same thing in a join to a derived table.
Other things in a query that can affect performance include using SARGable1 where clauses instead of non-SARGable ones, selecting only the fields you need and never using select * (especially not when doing a join as at least one field is repeated), using a set-bases query instead of a cursor, avoiding using a wildcard as the first character in a a like clause and on and on. There are very large books that devote chapters to more efficient ways to write queries.
1 "SARGable", for those that don't know, are stage 1 predicates in DB2 parlance (and possibly other DBMS'). Stage 1 predicates are more efficient since they're parts of indexes and DB2 uses those first.