firebird performance on tpch query - query-optimization

I am working on tpch benchmark which has a set of 22 queries. in query number 15 there is a view involved, after creating the view when i go to run query everything just freezes no result can anyone help me in this. by the way on Postgres same query comes back in 3.68 seconds.View and query is below
create view revenue0 (supplier_no, total_revenue) as
select
l_suppkey,
sum(l_extendedprice * (1 - l_discount))
from
lineitem
where
l_shipdate >= date '1997-05-01'
and l_shipdate < dateadd(month, 3, date '1997-05-01')
group by
l_suppkey;
query
select
s_suppkey,
s_name,
s_address,
s_phone,
total_revenue
from
supplier,
revenue0
where
s_suppkey = supplier_no
and total_revenue = (
select
max(total_revenue)
from
revenue0
)
order by
s_suppkey;

Related

SSRS: Why am I getting this aggregation?

I've recently uncovered that SSRS is doing a bizarre aggregation and I really don't understand why. In this report I'm building, as with other SQL queries I've built, I have a tendency to take preliminary results from an initial query, throw them into a temp table, and then perform another query and joining on that temp table to get my 'final' results I need to display. Here's an example:
--1. This query fetches all available rows based on the day (must be last day of month)
SELECT DISTINCT Salesperson ,c.Cust_Alias ,cost ,eomonth(CreateDate) createdate ,FaxNumber
INTO #equip
FROM PDICompany_2049_01.dbo.Customers c
JOIN PDICompany_2049_01.dbo.Customer_Locations cl ON c.Cust_Key = cl.CustLoc_Cust_Key
JOIN ricocustom..Equipment_OLD e ON e.FaxNumber = c.Cust_ID + '/' + cl.CustLoc_ID
JOIN PDICompany_2049_01.dbo.Charges ch ON ch.Chg_CustLoc_Key = cl.CustLoc_Key
WHERE Salesperson = #Salesperson
AND ch.Chg_Balance = 0
--2. This query fetches first result set, but filters further for matching date variable
SELECT DISTINCT (cost) EquipCost ,Salesperson ,DATEPART(YEAR, CreateDate) YEAR
,DATEPART(MONTH, CreateDate) MONTH ,Cust_Alias ,FaxNumber
INTO #equipcost
FROM #equip
WHERE Salesperson = #Salesperson
AND DATEPART(MONTH, CreateDate) = DATEPART(MONTH, #Start)
AND DATEPART(year, CreateDate) = DATEPART(year, #Start)
ORDER BY Cust_Alias
--3. Finally, getting sum of the EquipCost, with other KPI's, to put into my final result set
SELECT sum(EquipCost) EquipCost ,Salesperson ,YEAR ,MONTH ,Cust_Alias
INTO #temp_equipcost
FROM #equipcost
GROUP BY Salesperson ,year ,month ,Cust_Alias
Now I am aware that I could have easily reduced this to 2 queries instead of 3 in hindsight (and I have since gotten my results into a single query). But that's where I'm looking for the answer. In my GUI report, I had a row that was showing to have 180 for equipcost, but my query was showing 60. It wasn't until I altered my query to a single iteration (as opposed to the 3), and while I'm still getting the same result of 60, it now displays 60 in my GUI report.
I actually had this happen in another query as well, where I had 2 temp table result sets, but when I condensed it into one, my GUI report worked as expected.
Any ideas on why using multiple temp tables would affect my results via the GUI report in SQL Report Builder (NOT USING VB HERE!) but my SQL query within SSMS works as expected? And to be clear, only making the change described to the query and condensing it got my results, the GUI report in Report Builder is extremely basic, so nothing crazy regarding grouping, expressions, etc.
My best guess is that you accidentally had a situation where you did not properly clear the temp tables (or you populated the temp tables multiple times). As an alternative to temp tables, you could instead use table variables. Equally you could use a single query from the production tables -- using CTE if you want it to "feel" like 3 separate queries.

SQL Query Returns 0 Records Eventhough Records Exist in Table

I am having a bit of a problem with one of my select queries.
I have a view on which I'm running my select query on to retrieve a set of results (through the asp.net web application using a database connect class). I do not get any results.
But rows exist in my view which match the selection criteria in my view.
And the funny thing is, if I run the same query in SQL Server Management Studio, I am getting the expected results.
Any suggestions as to why this is happening?
Additional info:
My view:
CREATE VIEW [dbo].[V_Dashboard]
AS
SELECT
CBUName AS CBU, Brand AS brand, AccountName AS account,
DATEPART(wk, DueDate) AS Week, TeamMemeber AS [BEL Contact],
IsTaskCompleted AS isTaskCompleted,
[Contact Person] AS buyerContact, TaskType AS taskType,
LocationId
FROM
dbo.V_ContactsToBeCompleted
WHERE
(YEAR(DueDate) = YEAR(GETDATE())) AND (LocationId = 1)
Query I'm trying to execute that returns 0 records:
SELECT
[taskType], [buyerContact], [Week]
FROM
[customerRelationshipIndexDB].[dbo].[V_Dashboard]
WHERE
(CBU = 'EU')
AND (brand = 'M&S')
AND (account = 'M&S-T61')
AND ([BEL Contact] = 'gayaneew')
AND ([Week] BETWEEN 51 AND 51)
ORDER BY
[Week], [taskType], [buyerContact]

Querying a running-percentage over a date range from MSSQL?

I want to graph the % of users over time that have their Twitter account connected. The number of users changes constantly, and so does the % of them that connect their Twitter account.
The table has a user account specific createDateTime column as well as a tw_connectDateTime column.
Let's say I'm interested in the trend of % connected over the last 7 days. Is there a way I can have MSSQL calculate the percentage for every day in the specified range, or do I need to do it myself using multiple queries?
Doing it in app logic would look something like (pseudocode):
for day in days:
query:
select
count(userId) as totalUsers
,c.connected
,cast(c.connected as float)/count(userId) as percentage
from
Users
outer apply (
select
count(userId) as connected
from
Users
where
tw_connectDateTime <= $day
) as c
where
createDateTime <= $day
group by
c.connected
What I'm unsure of is how, if it's possible, to expand this to run for each day, so that the results include the date as a column and the same values that I would get from running the above query for each date in the range.
Is it possible? If so, how?
actually you can use your query joined with days, like this:
with cte_days as (
select #DateStart as day
union all
select dateadd(dd, 1, c.[day]) as [day]
from cte_days as c
where c.[day] < #DateEnd
)
select
d.[day],
count(u.userId) as totalUsers,
c.connected,
cast(c.connected as float)/count(u.userId) as percentage
from cte_days as d
inner join Users as u on u.createDateTime <= d.[day]
outer apply (
select
count(T.userId) as connected
from Users as T
where T.tw_connectDateTime <= d.[day]
) as c
group by d.[day], c.connected

Transform server status data to running 24 hour tabular format

I need to display running server status, in an asp.net grid view using c#, for the last 24 hours in 5 minute increments. The data is in SQL Server records of the form: HostName, RecordDate, RecordTime, Status. I need to transform the data into tabular format to load a grid view control. Transform to something like: HostName, Date, 00:00 status, 00:05 status, ..., 23:55 status. One of the problems, of course, is the user can access the web page at any time. The column names must be the 5 minute increment time, as 15.30, 15.35, etc. They'll always be the same, as 24 hours will be displayed, but will be in a different order, and potentially cross dates, depending upon when the user logs into the web site. I hope I've explained this well enough. All options are on the table: linq, linq to sql, linq to xml, etc.
Thanks for any help.
I will offer a T-SQL solution. You need a date table that holds the 5-minute intervals for the day in question. Left join that with your AccessLog (or whatever it's called) table where the access time is within each time range, and do whatever aggregations you want. This will give you the vertical list. Then you need to PIVOT that to make your TimeRanges into columns (search for SQL server PIVOT operator).
Below is the rough SQL. After that, you just need to wrap the results into a pivot.
declare #myDate SMALLDATETIME = '20130415';
;with TimeRanges as (
SELECT TOP 288 DateAdd(minute, (Row_Number() over (order by sc1.Name) -1) * 5 , #myDate) TimeRangeMin
, DateAdd(minute, Row_Number() over (order by sc1.Name) * 5 , #myDate) TimeRangeMax
FROM Master.dbo.SysColumns sc1, Master.dbo.SysColumns sc2
)
select convert(varchar(5), TimeRangeMin, 114) AS TimeRange, COUNT(*)
from TimeRanges t
LEFT JOIN AccessLog a on a.AccessTime >= t.TimeRangeMin and a.AccessTime < t.TimeRangeMax
GROUP BY convert(varchar(5), TimeRangeMin, 114);

Count number of 'overlapping' rows in SQL Server

I've been asked to look at a database that records user login and logout activity - there's a column for login time and then another column to record logout, both in OLE format. I need to pull together some information about user concurrency - i.e. how many users were logged in at the same time each day.
Do anyone know how to do this in SQL? I don't really need to know the detail, just the count per day.
Thanks in advance.
Easiest way is to make a times_table from an auxiliary numbers table (by adding from 0 to 24 * 60 minutes to the base time) to get every time in a certain 24-hour period:
SELECT MAX(simul) FROM (
SELECT test_time
,COUNT(*) AS simul
FROM your_login_table
INNER JOIN times_table -- a table/view/subquery of all times during the day
ON your_login_table.login_time <= times_table.test_time AND times_table.test_time <= your_login_table.logout_time
GROUP BY test_time
) AS simul_users (test_time, simul)
I think this will work.
Select C.Day, Max(C.Concurrency) as MostConcurrentUsersByDay
FROM
(
SELECT convert(varchar(10),L1.StartTime,101) as day, count(*) as Concurrency
FROM login_table L1
INNER JOIN login_table L2
ON (L2.StartTime>=L1.StartTime AND L2.StartTime<=L1.EndTime) OR
(L2.EndTime>=L1.StartTime AND L2.EndTime<=L1.EndTime)
WHERE (L1.EndTime is not null) and L2.EndTime Is not null) AND (L1.ID<>L2.ID)
GROUP BY convert(varchar(10),L1.StartTime,101)
) as C
Group BY C.Day
Unchecked... but lose date values, count time between, use "end of day" for still logged in.
This assumes "logintime" is a date and a time. If not, the derived table can be removed (Still need ISNULL though). of course, SQL Server 2008 has "time" to make this easier too.
SELECT
COUNT(*)
FROM
(
SELECT
DATEADD(day, DATEDIFF(day, logintime, 0), logintime) AS inTimeOnly,
ISNULL(DATEADD(day, DATEDIFF(day, logouttime, 0), logintime), '1900-01-01 23:59:59.997') AS outTimeOnly
FROM
mytable
) foo
WHERE
inTimeOnly >= #TheTimeOnly AND outTimeOnly <= #TheTimeOnly

Resources