/    Sign up×
Community /Pin to ProfileBookmark

SLOW SQL code..

Is there a way of simplifying this, in MYSQL Admin it took over 20 seconds to run, it’s been run inside a class so could I make it more generic but then filter results in PHP code?

“`
SELECT p.ID, p.ProductName, p.Price, p.SpecialPrice, p.ProductDetail, p.ProductImage, p.ProductStatus, p.ListingType, p.CategoryID, p.DateCreated, COUNT(i.InventoryID) As Qnty
FROM `products` p
LEFT JOIN `inventory` i ON i.ProductID = p.ID
WHERE i.OrderID IS NULL
group by p.ID
HAVING Qnty > 0 or p.ListingType = 0
“`

to post a comment
PHP

10 Comments(s)

Copy linkTweet thisAlerts:
@NogDogNov 22.2020 — I've never used HAVING clauses (that I recall, anyway), so don't know what the "gotchas" are, though I see in the MySQL manual, "Do not use HAVING for items that should be in the WHERE clause," which would apply to the p.ListingType = 0 portion. If you remove that clause and find it then runs much faster (hopefully a fraction of a second), then maybe it would make sense to filter it in the code. E.g. if you loop through the result rows:
<i>
</i>while($row = $stmt-&gt;fetch()) {
if($row['ListingType'] != 0 and $row['Qnty'] == 0) {
continue;
}
// otherwise do whatever you do with each row
}

If my brain was fresher, I might see a better way to do it purely in SQL, but at the moment it's not jumping out at me. :(
Copy linkTweet thisAlerts:
@sibertNov 22.2020 — > @kiwis80#1625274 WHERE i.OrderID IS NULL

> group by p.ID

> HAVING Qnty > 0 or p.ListingType = 0


Does this make any difference?

``<i>
</i>SELECT p.ID, p.ProductName, p.Price, p.SpecialPrice, p.ProductDetail, p.ProductImage, p.ProductStatus, p.ListingType, p.CategoryID, p.DateCreated, COUNT(i.InventoryID) As Qnty
FROM
products p
LEFT JOIN
inventory i ON i.ProductID = p.ID
WHERE i.OrderID IS NULL AND (Qnty&gt;0 OR p.ListingType=0)
GROUP BY p.ID<i>
</i>
``
Copy linkTweet thisAlerts:
@kiwisauthorNov 22.2020 — @sibert#1625278

#1054 - Unknown column 'Qnty' in 'where clause'
Copy linkTweet thisAlerts:
@sibertNov 22.2020 — > @kiwis80#1625279 Unknown column 'Qnty' in 'where clause'

Yes, I did not see the count() in your long query. Sorry.

But you can try avoid using alias:

HAVING COUNT(i.InventoryID) &gt; 0 or p.ListingType = 0
Copy linkTweet thisAlerts:
@kiwisauthorNov 22.2020 — When I remove the HAVING alias, I get this

Showing rows 0 - 24 (109 total, Query took 0.0410 seconds.)

In mySQL but it's still taking 10-15 seconds. I can count it out.
Copy linkTweet thisAlerts:
@SempervivumNov 22.2020 — What's confusing me is this:

**Query took 0.0410 seconds**

Makes me suspect that the issue is not caused by the query itself but by the PHP environment.
Copy linkTweet thisAlerts:
@kiwisauthorNov 22.2020 — OMG - I'm using a test database, the inventory table has over 55,000 rows!

Someone else must have coded something in error and loaded so much data. Live has 300 rows lol.

Instant difference.
Copy linkTweet thisAlerts:
@NogDogNov 22.2020 — > @kiwis80#1625283 the inventory table has over 55,000 rows!

If things are indexed as needed, that really shouldn't matter (most of the time). Make sure any columns used in the ON portion of joins, as well as in the WHERE clause are indexed -- just in case the business grows and some day you actually have thousands of items in the inventory. ;)
Copy linkTweet thisAlerts:
@kiwisauthorNov 22.2020 — @NogDog#1625285

When i set the table up, it was set as auto increment and index as primary?

Is this correct or should it be Index?

What's the difference?
Copy linkTweet thisAlerts:
@NogDogNov 23.2020 — Basically any column (or even group of columns) can be indexed, and each index can optionally be defined as unique. Your primary key for a table is a unique index, but any other column(s) can also be indexed, uniquely or not. Each index essentially creates another table-like structure that is optimized for finding/sorting values in that column. The reason you don't just index everything (normally?) is that every insert/update has to update those indexes, too, so you usually don't want to make it do more than it has to (though I don't think I've ever run into a situation where it mattered).

Presumably Product.ID is your primary key, so that's already indexed. Since you are joining inventory to it via its ProductID column, you'd want an index on inventory.ProductID to optimize that comparison operation. Likewise, if you're looking at i.OrderID in the where clause, you'll want an index on it, as well as p.ListingType if you're doing that comparison.

The result is that the DBMS does not have to search the entire table to find what it needs to know, but can instead do an optimized search against the index thingy (technical term ;) ).
×

Success!

Help @kiwis spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 4.25,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,
)...