Improve pagin count method speed with Linq on large amount of data - c#

I'have a count method to paginate a grid, that return a number around 2 millions, I wan't to improve it speed with a query like this, but on Linq:
SELECT count(*)
FROM (SELECT ROW_NUMBER() OVER (ORDER BY id) AS Row, Id
FROM myTable ) t
WHERE Row between 0 and (pageSize*visiblePages)+1 -- The number 1 is to check if there is another set of 1 or more pages
My problem is, I don't need to count 2 millions for a page that will show that I have 11 pages. The method to retrieve only 10 results works fine, but I can't count with the row_number

Maybe you can use LINQ's Take or Skip like this : http://msdn.microsoft.com/en-us/library/bb386988%28v=vs.110%29.aspx
Also check this VS gallery's pager control for MVC: http://en.webdiyer.com/

Related

Retrieving the last values from the database - should the results be sorted?

The database stores the currency exchange rate on a given day. Each day, one currency exchange value is collected and stored in the database as:
ID (int, AI)
VALUE
DATE
1
2.5
20.01.2021
2
2.7
21.01.2021
3
2.6
22.01.2021
If I would like to calculate the average exchange rate from the last 10 days, should I first sort the data by date and only retrieve the last 10 records when downloading the data, or is it enough to download the last 10 records from the database without sorting?
You can simply do in SQL Server database
SELECT TOP 10 AVG(VALUE) AS AverageRate
FROM YourTable
ORDER BY Id DESC
Concept should be same in other relational databases.
Tables (and table expressions such as views and CTEs) in SQL represent unordered sets. To get data in a particular order, you must specify an ORDER BY clause.
In fairly generic SQL you can do
SELECT AVG(VALUE) AS AverageRate
FROM (
SELECT VALUE
FROM YourTable AS t
ORDER BY Id DESC
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY
) AS t
In some RDBMSs, instead of OFFSET FETCH, you use either LIMIT or TOP to achieve the same effect. You still need ORDER BY.
You can do it in both ways.
If you're using SQL with Dapper or ADO.NET, then you can write a query.
It should be sorted if you need the last 10 values
SELECT TOP 10 AVG(your value) AS average
FROM YourCurrencyExchangeTable
ORDER BY DATE DESC
If you're using EntityFrameWorkCore, you can write
var avg = db.yourDbContext
.Where(c => c.Date >= tenDaysAgoDate)
.Average(c => c.yourValue)
I hope my answer helps :)
Basically you have to sort first ( on date) and then get the last 10 values, so you're on the right track.

EF - IQueryable - two selects with one db call

I am carrying out a pretty normal select data from table using Entity Framework Core and IQueryable. I am using paging in my search so want to fetch rows x to y, depending on the page size and current page.
Here's my code:
_dbContext.Orders.Where(o => o.UserId == userId)
.Skip((pageNo - 1) * pageSize).Take(pageSize).ToListAsync();
And resulting SQL:
SELECT [o].[UserId], [o].[OrderId], [o].[OrderDate], [o].[OrderType], [o].[FromNameAddressId], [o].[ToNameAddressId], [o].[Status]
FROM [Orders] AS [o]
WHERE [o].[UserId] = 12
ORDER BY (SELECT 1) OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY;
The problem I'm facing is that I also want to return the total record count as part of the query results and end up (currently) having to do that as a separate call to the db.
Here is my code:
_dbContext.Orders.Where(o => o.UserId == userId).CountAsync();
And resulting SQL:
SELECT COUNT(*) FROM [Orders] AS [o] WHERE [o].[UserId] = 12;
I am looking to make this more efficient, so was looking to either return the total record count as part of the first query OR to run the two selects with one db call rather than two. Has anyone achieved this before? I'm fairly new to Entity Framework, so this is probably fairly straight forward to achieve.
Thanks in advance for any pointers!

MS Access SQL, SELECT last five highest values in a column

MS Access SQL, SELECT last five highest values in a column
For example I have table named games, I want top five games with highest likes.
Something like this:
select top 5 *
from games
order by likes desc, id desc
I have added a "tie-breaker" to the order by clause to prevent access returning more than 5 records, i.e. the primary key.
Thanks to #Fionnuala for pointing out this issue with Access. For more info, see here

picking last records inserted into table [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have inserted 4 records into table1, and then 5 records and then 3 records.
Now I want to pick up last 3 records or say any number of records but inserted at last. How I will get those ?
Actually scenario is that in gridview 1 user would select say 3 records by help of checkbox field and then these 3 records will be inserted in to table1 and then store procedure will pick these last inserted 3 reocrds and assign it to RDLC report. All things are done but just don't know how to pick last inserted any number of records.
By definition, a table is an unordered set of rows. There is no way to ask SQL Server which row was inserted last unless you are doing so in the same batch as the insert. For example, if your table has an IDENTITY column, you can say:
INSERT dbo.table(column) values (...)
SELECT SCOPE_IDENTITY();
But that too will give you the last first identity column.
What you can do here is that you can take the help of timestamp and define that in a separate column of the table.
ALTER TABLE dbo.table ADD DateInserted DEFAULT CURRENT_TIMESTAMP;
Define stored procedure with the #lastrows count that you will store in your service layer to call.
CREATE PROC sp_GetLastInsertedRows(#lastrows int)
AS
;WITH x AS (SELECT *, r = ROW_NUMBER() OVER (ORDER BY DateInserted DESC)
FROM dbo.table)
SELECT * FROM x WHERE r <= N;
This way you get the last N number of rows inserted in the last transaction.
you can use below menioned query
SELECT column_name FROM table_name
ORDER BY column_name DESC
LIMIT 3;
Okay, so you're going to need something a bit more flexible. Right now you may have just one user, and right now you may be running the report immediately after executing the INSERT statements, but what you really need to know is what rows are new since the last time you looked.
One good way of doing this is adding a DATETIME NULL field to the row; let's call it processed_date. This field will be updated by the stored procedure that picks them up for the report. Something like this:
SELECT * FROM tbl1
INTO #report_tbl
WHERE processed_date IS NULL
UPDATE tbl1
SET processed_date = GETDATE()
WHERE id_field IN (
SELECT id_field
FROM #report_tbl
)
Now you are sure to pick up the rows that "haven't been looked at."

Implementing numeric pagination with asp.net

Hai guys,
I have nearly 20 pages in my website .... Every page has a gridview which has thousands of records bind to it... Now i want to implement custom pagination to all those grids.... Guys can some one give a pagination class which can be reusable for all those pages
Your not really going to get a one size fits all class to do this, thats why its called custom paging.
Just a rough guide as to how I have implemented this in the past.
Store the current page number somewhere Querystring/Session/Wherever
When you call your data method/stored procedure to ask for the data pass in the page number and amount of records per page you want.
ammend you stored procedure/data method to only return records in these bounds, it will also need to return a count of the total records so the application knows how many pages there are.
Here is simple example of how you could achieve paging in your stored procedures using SQL2005/2008 (Slightly more to it in 2000)
CREATE PROCEDURE GetTowns
(
#OutTotalRecCount INT OUTPUT,
#CurrentPage INT,
#PageSize INT
)
AS
SELECT * FROM
(
SELECT
ROW_NUMBER() OVER (ORDER BY TownName) AS Row,
TownId,
TownName
FROM Towns
) AS TownsWithRowNumbers
WHERE Row >= (#CurrentPage - 1) * #PageSize + 1 AND Row <= #CurrentPage*#PageSize
SELECT #OutTotalRecCount = COUNT(*) FROM Towns
Not sure about a "class", but here are a couple of links:
.NET 3.5
.NET 2.0
p.s. If you use DataSet as your DataSource, paging and sorting is supported out of the box.

Categories

Resources