{"id":406,"date":"2025-08-27T21:03:20","date_gmt":"2025-08-27T21:03:20","guid":{"rendered":"https:\/\/1v0.net\/blog\/?p=406"},"modified":"2025-08-27T21:03:21","modified_gmt":"2025-08-27T21:03:21","slug":"how-to-speed-up-laravel-with-database-indexing","status":"publish","type":"post","link":"https:\/\/1v0.net\/blog\/how-to-speed-up-laravel-with-database-indexing\/","title":{"rendered":"How to Speed Up Laravel with Database Indexing"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><strong>How to Speed Up Laravel with Database Indexing<\/strong><\/h2>\n\n\n\n<p>As your Laravel app scales, database queries often become the bottleneck. A single missing index can slow down a query from milliseconds to seconds. Indexing helps the database find rows faster by creating lookup structures on columns. In this guide, we\u2019ll cover different types of indexes, how to create them with migrations, and how to verify performance improvements.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n\n<h2 class=\"wp-block-heading\"><strong>1 &#8211; Why Indexing Matters<\/strong><\/h2>\n\n\n\n<p>Without indexes, databases must scan entire tables to find records. With indexes, searches are optimized like looking up words in a dictionary. The bigger your tables, the more critical indexes become. For high-traffic Laravel apps, indexing is as important as caching and queues (see <a href=\"\/blog\/10-proven-ways-to-optimize-laravel-for-high-traffic\">10 Proven Ways to Optimize Laravel for High Traffic<\/a>).<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n\n<h2 class=\"wp-block-heading\"><strong>2 &#8211; Adding Indexes in Migrations<\/strong><\/h2>\n\n\n\n<p>Laravel migrations make it easy to add indexes when creating or modifying tables.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ database\/migrations\/2025_08_27_000001_add_indexes_to_users.php<\/span>\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Database<\/span>\\<span class=\"hljs-title\">Migrations<\/span>\\<span class=\"hljs-title\">Migration<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Database<\/span>\\<span class=\"hljs-title\">Schema<\/span>\\<span class=\"hljs-title\">Blueprint<\/span>;\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Illuminate<\/span>\\<span class=\"hljs-title\">Support<\/span>\\<span class=\"hljs-title\">Facades<\/span>\\<span class=\"hljs-title\">Schema<\/span>;\n\n<span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">Migration<\/span> <\/span>{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">up<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">void<\/span>\n    <\/span>{\n        Schema::table(<span class=\"hljs-string\">'users'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">(Blueprint $table)<\/span> <\/span>{\n            $table-&gt;index(<span class=\"hljs-string\">'email'<\/span>);\n            $table-&gt;index(&#91;<span class=\"hljs-string\">'first_name'<\/span>, <span class=\"hljs-string\">'last_name'<\/span>]); <span class=\"hljs-comment\">\/\/ composite index<\/span>\n        });\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">down<\/span><span class=\"hljs-params\">()<\/span>: <span class=\"hljs-title\">void<\/span>\n    <\/span>{\n        Schema::table(<span class=\"hljs-string\">'users'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">(Blueprint $table)<\/span> <\/span>{\n            $table-&gt;dropIndex(&#91;<span class=\"hljs-string\">'email'<\/span>]);\n            $table-&gt;dropIndex(&#91;<span class=\"hljs-string\">'first_name'<\/span>, <span class=\"hljs-string\">'last_name'<\/span>]);\n        });\n    }\n};<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This migration adds a single-column index on <code>email<\/code> and a composite index on <code>first_name + last_name<\/code>. The database can now quickly locate users by email or full name.<\/p>\n\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n\n<h2 class=\"wp-block-heading\"><strong>3 &#8211; Unique Indexes<\/strong><\/h2>\n\n\n\n<p>Indexes can also enforce uniqueness, preventing duplicate values.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ database\/migrations\/2025_08_27_000002_add_unique_index.php<\/span>\nSchema::table(<span class=\"hljs-string\">'users'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">(Blueprint $table)<\/span> <\/span>{\n    $table-&gt;unique(<span class=\"hljs-string\">'username'<\/span>);\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This ensures no two users can have the same <code>username<\/code>. The index speeds up lookups and enforces integrity at the same time.<\/p>\n\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n\n<h2 class=\"wp-block-heading\"><strong>4 &#8211; Full-Text Indexes<\/strong><\/h2>\n\n\n\n<p>For searching text columns, use full-text indexes. Supported in MySQL and PostgreSQL, they allow fast search with <code>MATCH ... AGAINST<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ database\/migrations\/2025_08_27_000003_add_fulltext_index.php<\/span>\nSchema::table(<span class=\"hljs-string\">'posts'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">(Blueprint $table)<\/span> <\/span>{\n    $table-&gt;fullText(<span class=\"hljs-string\">'content'<\/span>);\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This lets you query posts with natural language search, far faster than scanning every row. For complex searches, combine full-text with Laravel\u2019s <a href=\"\/blog\/filtering-and-searching-with-laravel-eloquent-query-builder\">query builder filtering techniques<\/a>.<\/p>\n\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n\n<h2 class=\"wp-block-heading\"><strong>5 &#8211; Measuring Query Performance<\/strong><\/h2>\n\n\n\n<p>Always measure performance before and after adding indexes using <code>EXPLAIN<\/code> in MySQL\/Postgres.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"SQL (Structured Query Language)\" data-shcb-language-slug=\"sql\"><span><code class=\"hljs language-sql\"><span class=\"hljs-keyword\">EXPLAIN<\/span> <span class=\"hljs-keyword\">SELECT<\/span> * <span class=\"hljs-keyword\">FROM<\/span> <span class=\"hljs-keyword\">users<\/span> <span class=\"hljs-keyword\">WHERE<\/span> email = <span class=\"hljs-string\">'test@example.com'<\/span>;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">SQL (Structured Query Language)<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">sql<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Before adding the index, this query requires a full table scan. After the index, the DB uses an indexed lookup, which is dramatically faster on large datasets.<\/p>\n\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n\n<h2 class=\"wp-block-heading\"><strong>6 &#8211; Indexing Best Practices<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Index columns that are frequently used in <code>WHERE<\/code>, <code>JOIN<\/code>, and <code>ORDER BY<\/code>.<\/li>\n<li>Avoid indexing every column\u2014indexes add write overhead.<\/li>\n<li>Use composite indexes for multi-column searches.<\/li>\n<li>Regularly analyze queries with <code>EXPLAIN<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>Indexing complements caching and eager loading. For more on optimizing queries, see <a href=\"\/blog\/eager-loading-vs-lazy-loading-in-laravel-best-practices\">Eager Loading vs Lazy Loading in Laravel: Best Practices<\/a>.<\/p>\n\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>Database indexing is one of the most effective optimizations for Laravel apps. By adding single, composite, unique, and full-text indexes, you can cut query times dramatically. Always measure queries with <code>EXPLAIN<\/code> and avoid over-indexing. Combined with caching and queues, indexes help Laravel handle millions of queries efficiently.<\/p>\n\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n\n<h2 class=\"wp-block-heading\">What\u2019s Next<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"\/blog\/10-proven-ways-to-optimize-laravel-for-high-traffic\">10 Proven Ways to Optimize Laravel for High Traffic<\/a> \u2014 indexing is a key part of large-scale optimization.<\/li>\n<li><a href=\"\/blog\/caching-strategies-in-laravel-redis-vs-database-vs-file\">Caching Strategies in Laravel: Redis vs Database vs File<\/a> \u2014 combine indexes with caching for maximum performance.<\/li>\n<li><a href=\"\/blog\/eager-loading-vs-lazy-loading-in-laravel-best-practices\">Eager Loading vs Lazy Loading in Laravel: Best Practices<\/a> \u2014 avoid unnecessary queries on top of optimized indexes.<\/li>\n<\/ul>\n\n","protected":false},"excerpt":{"rendered":"<p>How to Speed Up Laravel with Database Indexing As your Laravel app scales, database queries often become the bottleneck. A single missing index can slow down a query from milliseconds to seconds. Indexing helps the database find rows faster by creating lookup structures on columns. In this guide, we\u2019ll cover different types of indexes, how [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":410,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[38,44,50],"class_list":["post-406","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-laravel","tag-database","tag-performance","tag-query-optimization"],"_links":{"self":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/406","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/comments?post=406"}],"version-history":[{"count":1,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/406\/revisions"}],"predecessor-version":[{"id":409,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/406\/revisions\/409"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media\/410"}],"wp:attachment":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media?parent=406"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/categories?post=406"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/tags?post=406"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}