How do I avoid timeouts with SqlServer full text search? - linq-to-sql

We're using SqlServer 2008. In SSMS, queries on the full text catalog might take 2-5 seconds the first time, but after that, return quite quickly.
On the other hand, running a query from via Linq2Sql will timeout.
Here's what we have:
The SQL Inline Table UDF
CREATE FUNCTION dbo.SearchArchiveFTS
(
#query nvarchar(255)
)
RETURNS #ret TABLE
(
ID NVarChar(12) NOT NULL,
snapshotDate DateTime NOT NULL,
-- about 10 more
)
AS BEGIN
declare #innerQuery nvarchar(255)
set #innerQuery = #query
insert into #ret
select ID,
snapshotDate,
-- about 10 more
from dbo.Archive a
where contains(a.*, #innerQuery)
return
Query in SSMS
select * from dbo.SearchArchiveFTS('query')
//3 seconds / 3k rows
Query in Linq2Sql
db.SearchArchiveFTS("query").ToArray();
// timeout exception
Any ideas on what the problem might be?

Check that your connection is not coming in with arithabort off. In SSMS it is ON
you can easily check like this
select arithabort,*
from sys.dm_exec_sessions
where is_user_process =1
just find the SPID that is hitting the DB
You also try to see what happens when you do this in SSMS
SET ARITHABORT OFF
select * from dbo.SearchArchiveFTS('query')
Does it now take a lot longer?
It is also possible that you are getting a bad plan from LINQ
You can clean out the procedure cache and memory buffers by running the following command
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
Just be aware that it will wipe out all the plans on the server and SQL Server will have to recreate all of those and also read in all the data from disk again.......

I agree with #SQLMenace, when somehthing runs fast in SSMS but not from the application, it is usually a connection difference.
However, why use a function for something like that?
if you must use a function, why not use a table value function like this:
CREATE FUNCTION dbo.SearchArchiveFTS
(
#query nvarchar(255)
)
RETURNS TABLE
AS RETURN
(
select ID,
snapshotDate,
-- about 10 more
from dbo.Archive a
where contains(a.*, #query)
);

The issue appears to be related to a feature of SQL Server, where the FTS indices are unloaded after a period of inactivity. A background job to keep them fresh solved the problem.

Related

Execution plan changes while executing parameterized query from application

We are working on SQL Server 2008. Java web application is used as the front end.
Each query that gets fired from application is executed as a stored procedure as shown in query #1.
We observed while executing simple SELECT and UPDATE query from application execution plan is different.
Query #1 takes 3 secs for execution:
declare #p1 int
exec sp_prepexec #p1 output, N'#P4 nvarchar(4000)',
N' SELECT KEY FROM dbo.DETAIL
WHERE KEY = #P4',N'SIND-60068635-R-202'
select #p1
Query #2 takes less than 1 sec for execution:
SELECT KEY
FROM DETAIL
WHERE KEY = 'SIND-60068635-R-202'
We observed execution plan for both queries are different. For 2nd query an index created on KEY is getting applied and hence query response is good, but that same index is not getting used for query #1, and hence query response time is bad.
Any suggestion how to fix this issue are appreciated.
Yes,There’s a problem, When we switch over to using a parameter in Stored Procedure, SQL Server isn’t able to make effective use of the filtered index. To resolve this issue one way is to use Index Hint like
SELECT * FROM <Table> WITH (INDEX(<indexName>))
but for that we have to keep using the same index name
Other way is to use string concatenation i.e. by forcing SQL Server to see the literal value (parameter)
e.g.
DECLARE #sql AS NVARCHAR(MAX) = N'';
DECLARE #p1 AS VARCHAR(10)='test'
SET #sql += 'SELECT KEY FROM dbo.DETAIL WHERE KEY = ' + CAST(#p1 AS NVARCHAR(10));
EXEC sp_executesql #sql;
Visit this url
- https://www.brentozar.com/archive/2013/11/filtered-indexes-and-dynamic-sql/
By changing nvarchar to varchar has helped for getting performance benefit (index scan to index seek). Also as JDBC is creating this issue while passing parameters as nvarchar instead of varchar . We referred following blog
https://blogs.msdn.microsoft.com/sqlcat/2010/04/05/character-data-type-conversion-when-using-sql-server-jdbc-drivers/

SQL Server 2008 stored proc running concurrently causing delays

I have a problem where it seems that when running the same stored procedure at the same time from two different instances of the same application it is timing out, and wondered if there was anything I could do to resolve it?
I believe the problem is in the way SQL Server 2008 handles itself, locking rows and executing the SPs...things I don't really know a whole lot about. The app uses ADODB.Command to execute the SP.
I have one VB6 exe (App.exe), running on the one server multiple times. This app calls a stored proc on the database which returns the next sequence number for that app. This sequence number field is unique for the instance of the application - there is 1 row in a table (tbl_SequenceNos) for each instance of the running application.
So for example, say we have running: App[a].exe and App[b].exe
tblSequenceNos looks like:
iAppNo| iNextSequenceNo
a | 1234
b | 4567
The stored procedure to get the next sequence number is relatively simple:
CREATE PROEDURE GetNextSequenceNo (#AppNo varchar(1), #NextSequenceNo int output)
AS
BEGIN
DECLARE #TempSequenceNo int
SELECT #NextSequenceNo = iNextSequenceNo
FROM tblSequenceNos
WHERE iAppNo = #AppNo
#NextSequenceNo = #NextSequenceNo + 1
UPDATE tblSequenceNos
SET iNextSequenceNo = #NextSequenceNo
WHERE iAppNo = #AppNo
END
When both App[a].exe and App[b].exe try to run this procedure to get their NextSequenceNo value, they are hanging for about 30Secs (ADO timeout?).
Because Each app never looks at the each others row, I thought that this would work concurrently without specifing an special Locking. Is there something I am missing? I thought perhaps I need to specify to lock the row only, not the whole table or Page? - I do not know what sql2008 does by default.
Any help is greatly appreciated!
Thank you in advance
Andrew
Your procedure is not thread safe and will produce incorrect results because between the select and the update multiple threads might get the same sequence nr.
CREATE PROCEDURE GetNextSequenceNo (#AppNo varchar(1), #NextSequenceNo int output)
AS
DECLARE #var table(seq int);
UPDATE tblSequenceNos
SET iNextSequenceNo = #NextSequenceNo + 1
OUTPUT inserted.iNextSequenceNo INTO #var;
WHERE iAppNo = #AppNo
select #NextSequenceNo = seq from #var
GO
Also make sure your iAppNo column is indexed. (This means an index on this column only or an index where this field is the first field in your index)

Function definition not properly passed to MySQL database using MySQL Workbench

I'm using MySQL 5.5 (x64) and MySQL Workbench 5.2 deployed locally on a Windows 7 workstation for development purposes. I used MySQL Workbench to build a schema with the following function definition:
CREATE FUNCTION `db`.`get_public_name` (GPN_entID INT) RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
DECLARE GPN_pubName VARCHAR(64);
SELECT public_name INTO GPN_pubName
FROM entity WHERE id_entity=GPN_entID LIMIT 1;
RETURN GPN_pubName;
END
I then attempt to "Forward Engineer" the schema to the database with the following options specified:
DROP Objects Before Each Create Object
Generate DROP SCHEMA
Add SHOW WARNINGS After Every DDL Statement
GENERATE INSERT Statements for Tables
After this, MySQL Workbench attempts to publish to the server:
CREATE FUNCTION `db`.`get_public_name` (GPN_entID INT) RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
DECLARE GPN_pubName VARCHAR(64);
SELECT public_name FROM entity WHERE id_entity = GPN_entID;
RETURN GPN_pubName;
END
This results in the following error:
Executing SQL script in server
ERROR: Error 1415: Not allowed to return a result set from a function
Upon closer examination, I noticed the "INTO" and "LIMIT" clauses of the SELECT statement have been removed from the original function definition. This looks like it might be a cached version of the function, but I have tried everything I can think of (short of uninstalling and reinstalling MySQL Workbench) to flush any such cache to reload the correct version, but to no avail.
So, why is this change happening and how do I prevent it from happening?
Try changing to this:
SELECT public_name FROM entity WHERE id_entity = GPN_entID LIMIT 1 INTO GPN_pubName;
I'm embarrassed; if it wasn't for the fact this may be useful to others, I'd just go ahead and delete this question to hide my shame.
It turns out I created two functions with the same name and MySQL Workbench happily let me do so. I didn't notice that was the case until I started going through the stored routines with a more careful eye. I was editing one, but the other one (which had the error) was never changed. Since publishing each function involved dropping any earlier version from the database, I probably wouldn't have noticed this until things weren't working properly.

could any one help me finding the Error with SP

create function Fun12(#InsCd varchar)
returns varchar(100)
as
begin
declare #ret varchar(52)
set #ret = (select [InsName] from [Assignment4].[dbo].[1466]
where rtrim(ltrim([InsCd]))= #InsCd)
return #ret
end
Executing:
declare #r varchar(50)
exec #r = dbo.Fun12 '436'
select #r
I am getting NULL value.
Could any one please help me finding the error?
You need to specify a size for your parameter #InsCd.
Some thing like this but you might want to use another value than 20 depending on the size of field InsCd.
create function Fun12(#InsCd varchar(20))
First, you should make sure that the code contained by the function actually returns something when you run it directly in SQL Server Management Studio (SSMS):
-- SQL
select InsName from [1466] where rtrim(ltrim([InsCd])) = '436';
In this case, I would use a stored procedure rather than a function. You could also use the SSMS Profiler (Tools > Profiler) to monitor the traffic to SQL Server. This way, you can actually see what gets executed, see the parameters for SPs, etc.

MySQL query browser procedure error code -1

I'm having a rather strange problem with MySQL. Trying to create a procedure to update some fields in the database (the code is below).
The problem is with the line that is currently commented. It seems that if no SELECT statements get executed during the procedure MySQL query browser will return an error code of "-1, error executing SQL query".
I tried the same thing in HeidiSQL and the error was "cannot return result set". So I suppose the question is do I always have to select something in the procedure, or is there some other thing I missed.
The query works fine when the comment is removed.
DELIMITER /
DROP PROCEDURE IF EXISTS updateFavourites /
CREATE PROCEDURE updateFavourites(quota INT)
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE artist_id,releases INT;
DECLARE c_artist Cursor FOR
SELECT Artist.id_number,COUNT(Artist.id_number) FROM Artist
JOIN CD ON CD.is_fronted_by = Artist.id_number
GROUP BY Artist.id_number;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'
SET done=1;
IF quota > 0 THEN
OPEN c_artist;
REPEAT
FETCH c_artist INTO artist_id,releases;
IF NOT done THEN
IF releases >= quota THEN
UPDATE CD SET CD.rating='favourite' WHERE CD.is_fronted_by = artist_id;
END IF;
END IF;
UNTIL done END REPEAT;
CLOSE c_artist;
-- SELECT 'Great success';
ELSE
SELECT CONCAT('\'quota\' must be greater than 0.',' Got (',quota,')');
END IF;
END /
DELIMITER ;
Here's the sql to create the tables and some data:
DROP TABLE IF EXISTS CD;
DROP TABLE IF EXISTS Artist;
CREATE TABLE Artist (
id_number INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50),
);
CREATE TABLE CD (
catalog_no INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,
is_fronted_by INT UNSIGNED,
rating ENUM ('favourite','top draw','good','so-so','poor','rubbish'),
CONSTRAINT fk_CD_Artist FOREIGN KEY (is_fronted_by) REFERENCES Artist(id_number) ON UPDATE CASCADE
);
INSERT INTO Artist VALUES(11,'Artist 1');
INSERT INTO Artist VALUES(10,'Artist 2');
INSERT INTO CD VALUES (7,11, 'top draw');
INSERT INTO CD VALUES (650,11,'good');
INSERT INTO CD VALUES (651,11,'good');
INSERT INTO CD VALUES (11,10,'favourite');
Query Browser is not for running scripts, just single query.
I tried your code by moving cursor into each query (except DELIMITER) and pressing Ctrl+Enter.
It created that stored procedure without problem. (just refresh schema on the left).
If you wish creating procedure, use menu "Script"->"Create stored procedure/function".
But better forget about QueryBrowser it is not supported at all (and actunally not useful).
If you have decent hardware and plenty resources, try Workbench 5.2 otherwise use SQLyog
Googling around, there are several reports of the same error, but little information to solve the problem. There's even a bug logged at mysql.com but it appears to have been abandoned without being resolved.
There's another StackOverflow question on the same error, but it's also unresolved.
All it means is that there is no result set from the query. Looking at the source code, it appears that sometimes an error status of MYX_SQL_ERROR is set when the query has no result set. Perhaps this is not an appropriate consequence?
I notice that when I use the mysql command-line client, it yields no error for calling a proc that returns no result set.
update: I tried to revive that MySQL bug report, and provide a good test case for them. They changed the bug from "no feedback" to "verified" -- so at least they acknowledge it's a bug in Query Browser:
[11 Dec 9:18] Sveta Smirnova
Bill,
thank you for the feedback. Verified
as described.
Although most likely this only be
fixed when MySQL Query Browser
functionality is part of MySQL
workbench.
I guess the workaround is to ignore the -1 error, or to test your stored procedures in the command-line mysql client, where the error does not occur.
The comment supposes the issue will disappear as the Query Browser functionality becomes part of MySQL Workbench. This is supposed to happen in MySQL Workbench 5.2. I'll download this beta and give it a try.
MySQL Workbench 5.2 is in Beta, but I would assume MySQL engineering can't predict when the Beta will become GA. Those kinds of predictions are hard enough under standard conditions, but there's a lot of extra uncertainty of MySQL's fate due to the unresolved Oracle acquisition.
update: Okay, I have tried MySQL Workbench 5.2.10 beta. I executed a stored procedure like this:
CREATE PROCEDURE FooProc(doquery SMALLINT)
BEGIN
IF doquery THEN
SELECT * FROM Foo;
END IF;
END
When I CALL FooProc(0) the response is no result set, and the status is simply "OK".
When I CALL FooProc(1) the response is the result of SELECT * FROM Foo as expected.
However, there's another bug related to calling procedures. Procedures may have multiple result sets, so it's hard to know when to close the statement when you execute a CALL query. The consequence is that MySQL Workbench 5.2 doesn't close the statement, and if you try to do another query (either CALL or SELECT) it gives you an error:
Commands out of sync; you can't run this command now.
MySQL doesn't support multiple concurrent open queries. So the last one must be closed before you can start a new one. But it isn't closing the CALL query. This bug is also logged at the MySQL site.
The bug about commands out of sync has been resolved. They say it's fixed in MySQL Workbench 5.2.11.
Try putting BEGIN and END blocks around the multiple statements in the IF block as such:
IF quota > 0 THEN
BEGIN
OPEN c_artist;
REPEAT
FETCH c_artist INTO artist_id,releases;
IF NOT done THEN
IF releases >= quota THEN
UPDATE CD SET CD.rating='favourite' WHERE CD.is_fronted_by = artist_id;
END IF;
END IF;
UNTIL done END REPEAT;
CLOSE c_artist;
END;
ELSE
SELECT CONCAT('\'quota\' must be greater than 0.',' Got (',quota,')');
END IF;