如何对运行缓慢的SQL查询进行基础优化?
Hey there! I totally get how frustrating it is to deal with a slow, unwieldy SQL query when you're still getting up to speed with the language—no optimization experience needed to start making improvements, though! Even without knowing your exact work environment, here are some beginner-friendly, actionable basics to help you speed things up:
Start with the execution plan
Almost every database (MySQL, PostgreSQL, SQL Server, etc.) has a tool to show you exactly how it processes your query. For example, prependEXPLAINto your query in MySQL (EXPLAIN SELECT ...) or useEXPLAIN ANALYZEin PostgreSQL. This will highlight bottlenecks like full table scans, slow joins, or inefficient sorting—think of it as an X-ray for your query to see where it's getting stuck.Add indexes to key fields
If your query uses fields inWHERE,JOIN ON, orORDER BYclauses to filter, link tables, or sort results, adding an index to those fields can drastically speed things up. For example, if you haveSELECT * FROM orders WHERE customer_id = 123, create an index like:CREATE INDEX idx_orders_customer_id ON orders(customer_id);Just don't overdo it—too many indexes slow down write operations (INSERT/UPDATE/DELETE), so only add them to fields you actually use in frequent queries.
Stop using
SELECT *—only fetch what you needSELECT *forces the database to pull every column from a table, even if you don't need most of them. If you only need order IDs and amounts, writeSELECT order_id, amount FROM ordersinstead. This cuts down on data transfer and memory usage, which makes a big difference for large tables.Avoid applying functions to fields in
WHEREclauses
Stuff likeWHERE DATE(create_time) = '2024-01-01'breaks index usage—your database can't use an index oncreate_timeif it has to calculateDATE(create_time)for every row. Rewrite it to use range checks instead:WHERE create_time >= '2024-01-01' AND create_time < '2024-01-02'This lets the database leverage the index directly.
Simplify your JOINs
First, double-check if all your JOINs are actually necessary—sometimes we accidentally include tables that don't add needed data. If you can, useINNER JOINinstead ofLEFT JOIN(when your business logic allows it) becauseLEFT JOINhas to retain all rows from the left table, which is more resource-intensive.Flatten nested subqueries
Deeply nested subqueries can confuse the database's optimizer, leading to slow execution. Try rewriting them as JOINs or using CTEs (Common Table Expressions, with theWITHkeyword) instead. CTEs are more readable and often get optimized better, like this example:WITH customer_order_counts AS ( SELECT customer_id, COUNT(*) AS total_orders FROM orders GROUP BY customer_id ) SELECT c.name, coc.total_orders FROM customers c JOIN customer_order_counts coc ON c.id = coc.customer_id;Skip
DISTINCTunless you really need itDISTINCTmakes the database do extra work to sort and remove duplicate rows. If your query results don't have duplicates (or you can adjust your JOIN logic to avoid them), leave it out—it'll save you a lot of processing time.Batch large result sets
If your query returns hundreds of thousands of rows, don't pull them all at once. UseLIMIT(MySQL/PostgreSQL) orTOP(SQL Server) to fetch data in chunks. For example:SELECT * FROM orders LIMIT 1000 OFFSET 0;Then use
OFFSET 1000for the next batch, and so on. This prevents your database and client from getting overwhelmed.
Start with the execution plan first—it'll point you to the biggest issues, then tackle one tip at a time. You don't have to fix everything at once!
内容的提问来源于stack exchange,提问作者TMiller

