How can you reproduce the same resultset with an optimal query automatically? - sql-server

is it possible to make MSSQL Management Studio produce a query that will reproduce a resultset, that you found prior, but use the best way possible to recreate it?
Maybe there is a way to tell the database which rows it shall return instead of it looking for the correct rows by the WHERE conditions? So once you found the rows, you dont have to search again?
So what I thought is: When you place a condition like
Where col1 = 10
The DB will check row 1 col1 for value 10, then row 2 col1 and so on..
Like it is searching, which takes time. Whereas if you could just make a statement that just directly asks for the specific row, you are faster?
I mean you dont need to search for the columns either: You just say give me col1 or col2 or whatever

The short answer is: NO
is it possible to make MSSQL Management Studio produce a query that will reproduce a result set, that you found prior
SQL Server Management Studio does not store your queries or the result SET which the queries return. It is simply a client application which pass the queries to the database server and present the result which the server returns.
On the other hand, SQL Server do store all the queries which you execute (for some time, depend on multiple parameters). Using the following query you can get the last queries which were executed by the server:
SELECT execquery.last_execution_time AS [Date Time], execsql.text AS [Script] FROM sys.dm_exec_query_stats AS execquery
CROSS APPLY sys.dm_exec_sql_text(execquery.sql_handle) AS execsql
ORDER BY execquery.last_execution_time DESC
GO
... use the best way possible to recreate it?
When you execute a query, then the server and the SSMS might provide some alerts and recommendation about the query, which can help us build a better query, but not the SQL Server and not the SQL Server Management Studio will build for you a better query based on a result SET of previous query
This is why we have DBA

Related

MS Access UPDATE query very slow

I have a very simple UPDATE query in Access which should update the underlying SQL Server. For whatever reason, Access does not pass the query to server but handles it by itself, i.e., it does an update query for each row. Since the table is huge, this runs forever.
This is the query as generated with the editor.
UPDATE dbo_myTable
SET dbo_myTable.myColumn = 'A'
WHERE dbo_myTable.myOtherColumn = 123;
If I run the same query as pure SQL it takes only seconds - as expected.
UPDATE dbo.myTable
SET dbo.myTable.myColumn = 'A'
WHERE dbo.myTable.myOtherColumn = 123;
The problem is not the 'A' value. If I change it from 'A' to Null the problem remains.
Background:
My actual update query is more complicated and involves joins and multiple conditions. While debugging the speed issues I could break it down to the above simple query which is already slow.
I used the SQL Server Profiler to confirm my guess that access does a query for each row instead of passing the whole query to the SQL Server.
Related:
I had a similar question a while ago: Force MS Access to send full query to SQL server . While the problem is the same - Access not passing the whole query - the solution has to be different because here there are really no special commands whatsoever here.
The syntax for update queries in Access is significantly different from that of SQL server, especially regarding joins. They can't be handed off to SQL server.
One of the main differences is that in Access, an update query write locks all included tables by default and can write to all of them, while in SQL server, you have a separate FROM section, and the query only write locks and writes to a single table.
Instead, use a passthrough query to execute an update query on SQL server if performance is an issue.
Perhaps you can fool Access to call a bulk update:
Sql = "UPDATE dbo.myTable SET dbo.myTable.myColumn = 'A' WHERE dbo.myTable.myOtherColumn = 123;"
CurrentDb.Execute Sql, dbQSPTBulk
The above dbqQSPTBulk is supposed to be used with dbQSQLPassthough
but you don’t have to.
If you use above, then only one update command is sent.
Credit: Albert Kallal

SQL Server : rows out of order

When I do a simple query using Microsoft SQL Server Management Studio I would expect the rows to be in order based on the ID column which is my primary key column.
For the most part the rows are in order but every once in awhile it will go from 98,99,100,1035,1036,1037,101 but when it jumps around it is in groups not just a single row out of order. The rows are added to the database using a simple INSERT from a ColdFusion script.
Is there a reason this is happening? I can do a ORDER BY so it is readable but if there is something I am doing incorrectly to start with I would like to fix my error.
Let me know if any more information would help.
MS SQL Server makes no guarantee about the order in which records are actually stored internally. So you can't depend on records coming out in the order of the primary key. If you want to order your result set, then use ORDER BY with an appropriate column; it's what it was designed for.

Paging for dynamic complex queries for SQL Server

I can't find an easy way to make paging for complex queries for SQL server. I need to write function that takes sql query as an argument (this query can include subqueries, order by statements, grouping etc.) and retrieve a particular page of results. In oracle it's easy by encapsulating such query with another select statement, but for SQL server I can't find any simillar way. What I would like to avoid is to parse input SQL statement. I'm using SQL server 2005
Paging in SQL Server 2005 and upwards is best done via ranking functions. However, given that an arbitrary SQL query is unsorted, you need to somehow specify what the sort shall be for this to work, which isn't really "compatible" with a generic solution like you're trying to make (*).
The suggested way to do it is like this (assuming the variables #PageSize with the number of items per page, and #Page as 1-based index to the page you want to retrieve):
WITH NumberedQuery AS (
SELECT ROW_NUMBER() OVER (ORDER BY q.SomeColumn) ix, q.*
FROM QueryToPage q
)
SELECT nq.*
FROM NumberedQuery nq
WHERE (nq.ix >= (#Page-1)*#PageSize) AND (nq.ix < #Page*#PageSize);
(*): Your approach with concatenating SQL code has several issues, it prevents the use of parametrized queries, it adds the risk of SQL injection, it hurts performance and it cannot solve the issue at hand if the order is unspecified.

Sql Server - user CTE in subquery

This question has been asked before -
How we can use CTE in subquery in sql server?
The only answer suggested was "Just define your CTE on top and access it in the subquery?"
This works, but I would really like to be able to use a CTE in the following scenarios -
as a subquery in a SELECT
as a derived table in the FROM clause of a SELECT
Both of these work in PostgreSQL. With Sql Server 2005, I get "Incorrect syntax near the keyword 'with'".
The reason I would like it is that most of my queries are constructed dynamically, and I would like to be able to define a CTE, save it somewhere, and then drop it in to a more complex query on demand.
If Sql Server simply does not support this usage, I will have to accept it, but I have not read anything that states that it is not allowed.
Does anyone know if it is possible to get this to work?
In SQL Server, CTE's must be at the top of the query. If you construct queries dynamically, you could store a list of CTE's in addition to the query. Before you send the query to SQL server, you can prefix the query with a list of CTE's:
; with Cte1 as (...definition 1...),
Cte2 as (...definition 2...),
Cte3 as (...definition 3...),
...
...constructed query...
This is assuming that you're constructing the SQL outside of SQL Server.
You could also consider creating views. Views can contain CTE's, and they can be used as a subquery or derived table. Views are a good choice if you generate SQL infrequently, say only during an installation or as part of a deployment.
SQL Server does not support this much-required feature. I too have been looking for help on this.
MS SQL Server does not support Temporary Views either as opposed to PostgreSQL. The above-mentioned solution is also likely to work only if all the CTE definitions could be generated before-hand and do not have conflicting names in each of the sub-queries either - the purpose being that these CTE definitions may be different for each level of a sub-query.
Sad but true !!!
Regards,
Kapil

Full Text Query takes minutes instead of sub seconds after upgrade

We just upgraded our SQL Server 2005 to SQL server 2008 R2 and noticed some performance problems.
The query below was already slow but now in 2008 it just times out. We rebuild the catalog to make sure its freshly made on 2008
DECLARE #FREETEXT varchar(255) = 'TEN-T'
select Distinct ...
from
DOSSIER_VERSION
inner join
DOSSIER_VERSION_LOCALISED ...
where
CONTAINS(DOSSIER_VERSION.*,#FREETEXT)
or
CONTAINS(DOSSIER_VERSION_LOCALISED.*,#FREETEXT)
The query takes minutes if you have both conditions enabled.
If you just put the following in the where
CONTAINS(DOSSIER_VERSION.*,#FREETEXT)
Its super fast. Same goes for the case if its just
CONTAINS(DOSSIER_VERSION_LOCALISED.*,#FREETEXT)
Since we are or'ing the results I would expect the time for this query to run to be less than the sum but as stated above it takes minutes/times out.
Can anyone tell me what is going on here? If I use a union (which is conceptually the same as the or) the performance problem is gone but I would like to know what issue I am running into here since I want to avoid rewriting queries.
Regards, Tom
See my answers to these very similar questions:
Adding more OR searches with
CONTAINS Brings Query to Crawl
SQL Server full text query across
multiple tables - why so slow?
The basic idea is that using LEFT JOINs to CONTAINSTABLE (or FREETEXTTABLE) performs significantly better than having multiple CONTAINS (or FREETEXT) ORed together in the WHERE clause.

Resources