-
Notifications
You must be signed in to change notification settings - Fork 293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Instrumentation.SqlClient Span has Duration of 0 sec #1736
Comments
Thanks @Mario-Hofstaetter! This looks suspicious, I'll take a look! The Activity created by the SqlClient instrumentation should start on I just tried a very small example, and I do get span duration in Jaeger as expected: using (var con =
new Microsoft.Data.SqlClient.SqlConnection("Data Source=localhost;Initial Catalog=master;Integrated Security=true;"))
{
con.Open();
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "select database_id from sys.databases; waitfor delay '00:00:05'";
var sw = new Stopwatch();
sw.Start();
using (var reader = cmd.ExecuteReader())
{
sw.Stop();
Console.WriteLine("ExecuteReader took: {0}", sw.ElapsedMilliseconds);
sw.Restart();
while (reader.Read())
{
}
sw.Stop();
Console.WriteLine("reader.Read() took: {0}", sw.ElapsedMilliseconds);
}
}
} I'll see if I can reproduce with a bigger example more similar to yours. |
Edit: @mbakalov I've nailed it down. Use this query, which I used to populate my demotable in the first place: SELECT TOP(1000) o1.object_id, o1.name FROM sys.objects o1 CROSS JOIN sys.objects o2 CROSS JOIN sys.objects o3; WAITFOR DELAY '00:00:04' Your I went from 5000 down until 300 Rows in TOP until the Duration was correct. Using this particular query and / or my database setup, the tipping point is exactly 306 Rows. With 305 Rows the Duration is correct. |
@Mario-Hofstaetter - sorry, missed the edit! You are right, this is a result of datareader's buffering behavior. It seems that
Using code like below I did some measurements on different queries using the StackOverflow DB: using var con =
new SqlConnection("Data Source=tcp:localhost;Initial Catalog=StackOverflow2013;Integrated Security=true;");
con.Open();
using var cmd = con.CreateCommand();
cmd.CommandText = "select top 500000 * from Users; waitfor delay '00:00:05'";
var sw = new Stopwatch();
sw.Start();
using var reader = cmd.ExecuteReader();
sw.Stop();
Console.WriteLine("ExecuteReader took: {0}", sw.ElapsedMilliseconds);
sw.Restart();
while (reader.Read())
{
}
sw.Stop();
Console.WriteLine("reader.Read() took: {0}", sw.ElapsedMilliseconds);
So this seems consistent with the buffering behavior mentioned here on StackOverflow and in MS docs: for a simple query like For some additional info I did some network captures to observe this more closely. Here is a capture for We send the query batch to the server in packet 26 and get roughly 8k-sized data packet back (no. 28) almost right away. And in another example for Packet no. 28 is now 5 seconds delayed because the data size is only 1.7k and the SQL server executed the |
@mbakalov Thanks for looking into this. Since I guess this is not something that can be fixed , what do you recommend? It is very unintuitive for the user that some spans of
PS: Happy new year |
Thanks @Mario-Hofstaetter, Happy New Year to you as well :) I agree, this behavior can sometimes be a bit confusing. Ultimately, I think you want to instrument both:
Even regardless of reader's "streaming" semantics, I still found the current instrumentation behavior to be super useful. A lot of (most?) queries I come across typically take a long time to even return the first row. Maybe due to a bad execution plan, or lack of indexes, or lots of I/O and CPU required to JOIN or sort through some intermediate results. The stuff DBAs usually look at. Current instrumentation works very well for that. There are of course a lot if interesting things happening within BTW, one exception to the "query taking time to return the first row" I typically see is with queries that return multiple datasets (that you go over with |
This looks like it's not something we're planning on, or can be, fixed, so I'm closing this as Not Planned. |
@martinjt It's not relevant for me anymore :) |
Since the issue is not fixed, nor documented, reopening this for consideration before stable release of this component. |
Bug Report
Runtime version
netcoreapp3.1
Symptom
I tested SqlClient instrumentation with a dummy app and noticed
the Duration of the SqlClient Span is always 0ms or 1ms. (See Screenshot)
My test SQL Statement has a sleep (
WAITFOR DELAY
) in it, so it takes at least a couple seconds even on localhost.It looks like the span is created after all sql work is done.
What is the expected behavior?
I expected to observe a span duration that is reflecting the actual execution time of the SQL Statement in the database.
Since the README does not contain any details / example,
I was expecting the Span to start on calling
Connection.Open()
orcommand.ExecuteReader()
(?)What is the actual behavior?
The autoinstrumented activity (span) has a duration of 0ms or 1ms on localhost. After closely looking at the reported
Start Times
one can see the span is started after opening the Connection and beforecommand.ExecuteReader())
:139.31ms
Post Open Connection
139.34ms
Demo
, servicelocalhost
, Duration1ms
140.47ms
Post ExecuteReader
It looks like the span is instantly stopped?
Reproduce
Result
The text was updated successfully, but these errors were encountered: