{"id":20930,"date":"2026-08-23T15:05:18","date_gmt":"2026-08-23T13:05:18","guid":{"rendered":"https:\/\/webhosting.de\/mariadb-query-optimizer-intern-erklaert-sql-tuning-insight\/"},"modified":"2026-08-23T15:05:18","modified_gmt":"2026-08-23T13:05:18","slug":"an-inside-look-at-the-mariadb-query-optimizer-sql-tuning-insights","status":"publish","type":"post","link":"https:\/\/webhosting.de\/en\/mariadb-query-optimizer-intern-erklaert-sql-tuning-insight\/","title":{"rendered":"An Inside Look at the MariaDB Query Optimizer: Fundamentals, Strategies, and Practical Applications"},"content":{"rendered":"<p>I'll explain the <strong>MariaDB Optimizer<\/strong> Real-world examples: how it creates plans, estimates costs, and why it sometimes gets it wrong. Here's how to read the SQL execution plan effectively, use indexes wisely, and guide the optimizer with facts rather than gut feelings.<\/p>\n\n<h2>Key points<\/h2>\n\n<p>To start, I'll briefly summarize the most important components so you can put the following sections into context and <strong>Overview<\/strong> keep.<\/p>\n<ul>\n  <li><strong>Phases<\/strong>: Parsing, preparing, optimizing, and executing make up the lifecycle of every query.<\/li>\n  <li><strong>Cost model<\/strong>: Time-based microsecond values control index selection, scans, and join order.<\/li>\n  <li><strong>Statistics<\/strong>: Cardinality and histograms determine the selectivity estimate.<\/li>\n  <li><strong>Transparency<\/strong>: EXPLAIN, EXPLAIN ANALYZE, and Optimizer Trace open the black box.<\/li>\n  <li><strong>Tuning<\/strong>: Indexes, query rewrites, ANALYZE TABLE, and cost parameters boost performance.<\/li>\n<\/ul>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/08\/mariaDB-query-plans-9842.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>The Lifecycle of a Query in MariaDB<\/h2>\n\n<p>Before a plan is formed, a query goes through four stages, which I specifically review on a daily basis in order to <strong>Causes<\/strong> to identify causes of slowness. During parsing, MariaDB converts SQL into an internal structure; syntax errors are detected at this stage. During preparation, the engine checks tables, columns, and potential indexes and performs simple transformations. Next comes optimization, during which candidate execution plans are calculated and evaluated using a cost model. During execution, the server implements the selected plan step by step: read, join, filter, return.<\/p>\n\n<p>I clearly categorize analysis errors by phase, because that way, solutions are implemented more quickly and <strong>Measures<\/strong> Take a targeted approach. Performance issues usually stem from optimization: incorrect estimates, missing indexes, or inefficient join sequences. Parsing errors are trivial, but the preparation phase can already involve techniques such as view resolution or subquery transformations. During execution, inefficiencies become painfully apparent if a full scan was selected earlier. That\u2019s why I start every investigation with a structured review of all four stages.<\/p>\n\n<h2>How the Optimizer Makes Decisions Internally<\/h2>\n\n<p>MariaDB operates on a cost-based approach and evaluates alternative execution plans using a <strong>Cost Function<\/strong>. For each variant, the server estimates the number of rows read, the selectivity of WHERE\/ON clauses, access types such as table scan, index scan, and range scan, as well as the time required for individual operations. Internally, the server distinguishes between `join_preparation` and `join_optimization`. In `join_preparation`, query rewrites, condition simplifications, subquery transformations, and view resolutions take place. `join_optimization` calculates join orders, checks index candidates via `ref_optimizer_key_uses`, estimates rows via range scans, and assigns conditions to specific tables as early as possible.<\/p>\n\n<p>This mechanism explains why a small filter in the wrong place can cause expensive <strong>Consequences<\/strong> If `attaching_conditions_to_tables` occurs late, the plan drags an unnecessary number of rows through joins. If statistics are out of date, `rows_estimation` and selectivity are incorrect; the optimizer then resorts to access paths that seem favorable but are actually slow. These are exactly the areas I focus on: better statistics, clearer predicates, and neatly sorted composite indexes. After that, the choice of execution plan often shifts noticeably.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/08\/MariaDBQueryOptKonferenz1234.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Pricing Model Starting with MariaDB 11.0<\/h2>\n\n<p>Current releases no longer evaluate work roughly based on weights, but rather using <strong>microseconds<\/strong> for specific storage operations. Parameters such as `optimizer_disk_read_cost`, `optimizer_disk_read_ratio`, and `optimizer_where_cost` bring the model closer to actual execution times. This allows the optimizer to compare an index range scan versus a full scan based on real-world time assumptions. LAST_QUERY_COST displays the estimated total cost and often correlates much better with reality than it used to. For data-intensive systems, this finer-grained approach pays off immediately.<\/p>\n\n<p>I carefully calibrate the model when hardware characteristics contradict the standard assumptions and thus the <strong>Plan Selection<\/strong> distort. NVMe SSDs, distributed storage, or specialized caches can significantly shift the disk ratio and read times. Minor adjustments to `optimizer_costs` cause MariaDB to favor sensible execution paths. I document every change and then check EXPLAIN ANALYZE to measure the impact. Without measurement, tuning remains a game of chance.<\/p>\n\n<h2>Selectivity, Statistics, and Histograms<\/h2>\n\n<p>Good estimates start with clean <strong>cardinality<\/strong> and reliable selectivity. MariaDB maintains statistics on different values for each column and can optionally use histograms for distributions. Uneven data in particular\u2014hotspots, Zipf distributions, seasonal patterns\u2014benefit from histograms. After major data changes, I run `ANALYZE TABLE` so that the optimizer can once again work with accurate data. Anyone who forgets to do this risks full scans, which are objectively incorrect.<\/p>\n\n<p>I'm scheduling ANALYZE as a regular job, tailored to <strong>Changes<\/strong> in terms of data volume and critical tables. For highly skewed column distributions, histograms help provide a realistic assessment of the selectivity of singular values. This reduces miscalculations in range scans and merge strategies. Combined with appropriate composite indexes, hit accuracy improves dramatically. The result: shorter execution times and less I\/O.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/08\/mariadb-query-optimizer-guide-4729.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>EXPLAIN and Reading Execution Plans<\/h2>\n\n<p>To make decisions transparent, I use EXPLAIN, EXPLAIN EXTENDED, and <strong>FORMAT=JSON<\/strong>. The standard columns provide a quick overview: id, select_type, table, type, possible_keys, key, key_len, ref, rows, and, if applicable, filtered. A `type=ALL` indicates a full scan, which is rarely desirable. `FORMAT=JSON` shows in detail how conditions were moved and which paths the optimizer evaluated. In a hosting context, I recommend the guide on <a href=\"https:\/\/webhosting.de\/en\/database-query-execution-plans-hosting-optimization-performance-insights\/\">Execution Plans in Hosting<\/a>, to link plan information with infrastructure impacts.<\/p>\n\n<p>To help me interpret the data quickly, I use a small table that briefly lists typical values and thus <strong>Misinterpretations<\/strong> prevented.<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>EXPLAIN field<\/th>\n      <th>Typical value<\/th>\n      <th>Practical Significance<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>type<\/td>\n      <td>ALL, range, ref, eq_ref, const<\/td>\n      <td>The further to the right, the more selective; ALL indicates a full scan.<\/td>\n    <\/tr>\n    <tr>\n      <td>possible_keys<\/td>\n      <td>Index List<\/td>\n      <td>Indices that fit in theory; if there are no candidates here, there is no structure.<\/td>\n    <\/tr>\n    <tr>\n      <td>key<\/td>\n      <td>Index Name<\/td>\n      <td>Index actually used; blank means no index is used.<\/td>\n    <\/tr>\n    <tr>\n      <td>rows<\/td>\n      <td>Number<\/td>\n      <td>Estimated number of lines read; significantly different from reality = poor statistics.<\/td>\n    <\/tr>\n    <tr>\n      <td>filtered<\/td>\n      <td>Percent<\/td>\n      <td>How much is passed through the filter; less is often better.<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<h2>Why the Optimizer Sometimes Gets It Wrong<\/h2>\n\n<p>No cost model fits every situation, so I'm making some adjustments <strong>Mistakes<\/strong> Targeted. Outdated statistics lead to incorrect row estimates and suboptimal join orders. Improperly constructed composite indexes prevent index usage with multi-column filters. Highly nested subqueries make effective rewrites difficult and block materialization. Missing or misleading filters force the engine to move many rows before useful predicates take effect.<\/p>\n\n<p>First, I check whether the query is formulated according to the <strong>Index<\/strong> What really helps: the left prefix rule, an appropriate sort order, and avoiding functions on columns in the WHERE clause. Then I check EXPLAIN ANALYZE to see if the actual execution supports the estimate. If not, I run ANALYZE TABLE and, if necessary, a rewrite. Only as a last resort do I resort to FORCE INDEX or hinting, because that can limit future optimizations.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/08\/mariadboptimizer_2219.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Using the Optimizer Trace Effectively<\/h2>\n\n<p>If EXPLAIN isn't enough, I enable the optimizer trace and monitor <strong>Decisions<\/strong> in the JSON log. There, I can see which plans were considered, rejected, or accepted. I can see why a condition took effect late or why an index wasn't shortlisted. The log also shows how conditions were rearranged. This view deepens my understanding and provides concrete levers for the next round of tuning.<\/p>\n\n<p>I save relevant sections of the trace along with the query hash and <strong>Parameters<\/strong>value. That way, I can later compare which change had which effect. The MariaDB Server documentation and various presentations within the ecosystem describe these fields in detail (Source: MariaDB Server documentation on the Query Optimizer and Optimizer Trace). With this tool, I can identify flawed assumptions faster than through trial and error. I save the most time when dealing with complex joins.<\/p>\n\n<h2>Practical Guide: Database Tuning Step by Step<\/h2>\n\n<p>I start every optimization with a clear <strong>Measurement<\/strong>. I identify problem queries through monitoring and the <a href=\"https:\/\/webhosting.de\/en\/mysql-slow-query-log-hosting-analyze-queryperf\/\">Slow Query Log<\/a>. Then I compare EXPLAIN with EXPLAIN ANALYZE to compare the execution plan with the actual results side by side. I adjust the index strategy to match the WHERE, JOIN, and ORDER BY clauses; I align composite indexes with the most frequent access points. I only use FORCE INDEX if the optimizer selects the wrong candidate despite having correct statistics.<\/p>\n\n<p>Each step involves maintaining the <strong>Statistics<\/strong>: ANALYZE TABLE on highly active tables; histograms for skewed distributions. I simplify unnecessary subqueries, materialize intermediate results as needed, and clean up old workarounds. For specialized hardware, I check optimizer_costs to ensure the microsecond model is accurate. I document every change with before-and-after values so that the impact remains traceable over time.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/08\/mariadb_query_optimizer_8390.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Common Optimizer Problems and Solutions<\/h2>\n\n<p>If EXPLAIN shows type=ALL even though possible_keys is filled, I first look at <strong>Selectivity<\/strong>. Often, the column order in the composite index is incorrect, or a function prevents the index from being used. In such cases, I reverse the order, remove problematic functions, or split predicates. If the join order is incorrect, I check whether early filtering is possible, for example, by bringing the more selective table to the front. Where appropriate, I convert subqueries into joins or TEMPORARY tables.<\/p>\n\n<p>I can also identify poor decisions by looking at values that deviate significantly <strong>rows<\/strong> between theory and practice. In that case, `ANALYZE TABLE` or a histogram on the affected column can help. If even correct statistics don't get the job done, I consider using explicit hints. Before doing so, I save cross-checks and measurement values to ensure that later versions of the optimizer aren\u2019t inadvertently hindered. Discipline in documentation pays off here.<\/p>\n\n<h2>Hosting Context and Operational Aspects<\/h2>\n\n<p>Query quality and infrastructure must be aligned; otherwise, the application is wasting its potential. <strong>Potential<\/strong>. Fast SSDs, consistent caches, and a clean configuration are the foundation on which the optimizer makes good decisions. High traffic leaves no room for full scans; just a few poor queries can slow down entire systems. For MySQL\/MariaDB environments in production, practical tips such as <a href=\"https:\/\/webhosting.de\/en\/mysql-optimizer-query-hosting-optimization-serverboost\/\">MySQL Optimizer<\/a> Helpful insights on combining strategy and platform. By considering this aspect, you can prevent bottlenecks before they escalate.<\/p>\n\n<p>I always link plan analysis to metrics related to <strong>I\/O<\/strong>, latency, and concurrency. If the values don't match the assumed cost model, I check the parameters. Then I look at buffer sizes, parallel workloads, and the distribution of hot sets. This approach allows me to run queries and manage resources smoothly and keep peak times under control.<\/p>\n\n<h2>Join and Access Paths in Practice<\/h2>\n\n<p>I clear up many misunderstandings by explaining the <strong>Types of Access<\/strong> carefully weigh one against the other. A <em>range<\/em>- or <em>ref<\/em>-Access almost always works <em>ALL<\/em>. For equality joins on unique keys (<em>eq_ref<\/em>) the plans are particularly stable. I also check to see if a <strong>Coverage Index<\/strong> fully satisfies the query: If all the required columns are included in the index, MariaDB avoids costly table lookups. <strong>Index Condition Pushdown (ICP)<\/strong> helps to evaluate additional WHERE conditions right in the index\u2014which reduces the number of rows returned and I\/O.<\/p>\n\n<p>About <strong>Index Merge<\/strong> MariaDB can combine multiple indexes (intersection\/union). This is useful for OR predicates or multiple selective conditions, but is often slower than a well-chosen composite index. I am also evaluating <strong>MRR<\/strong> (Multi-Range Read) and <strong>BKA<\/strong> (Batched Key Access). MRR sorts primary keys to be read in order to smooth out random I\/O; BKA bundles join lookups and is particularly effective for non-overlapping joins. In practice, I test BKA\/MRR using `optimizer_switch` and use `EXPLAIN ANALYZE` to check whether the I\/O patterns decrease. If, on the other hand, MariaDB resorts to <strong>Block Nested Loop<\/strong> (BNL), it's usually better to increase the join buffer (join_buffer_size)\u2014or to use a rewrite that allows for true index joins.<\/p>\n\n<pre><code>-- Example: Composite index for join + filter + order\nCREATE INDEX ix_orders_cust_status_created\n  ON orders (customer_id, status, created_at);\n\n-- Typical query\nSELECT *\nFROM orders o\nJOIN customers c ON c.id = o.customer_id\nWHERE o.status = 'open' AND o.created_at &gt;= '2026-01-01'\nORDER BY o.created_at DESC\nLIMIT 50;\n<\/code><\/pre>\n\n<p>Using the above index, the optimizer can choose the most selective order, evaluate filters early, and often perform the sort without requiring an additional file sort.<\/p>\n\n<h2>ORDER BY, GROUP BY, file sort, and temporary tables<\/h2>\n\n<p>Sorting and aggregating take time. I'll make sure that <strong>ORDER BY<\/strong> and <strong>GROUP BY<\/strong> can run in the order of the index. This works if the prefix and direction match exactly. Otherwise, a <strong>filesort<\/strong> with a sort buffer (sort_buffer_size) and, if necessary, a temporary table. If the result set contains wide TEXT\/BLOB columns, MariaDB performs faster <em>on disk<\/em> TEMP tables (Aria). I take precautions by selecting only the columns I need, loading large fields only at the end, or using prefixes with length limits.<\/p>\n\n<p>When performing aggregations, I use, whenever possible, <strong>Loose Index Scan<\/strong> (e.g., GROUP BY on the leading index component) and select composite indexes along the grouping. When intermediate results become large, materialization using sensible keys scales better than a single mega-join. I regularly monitor handler metrics and Created_tmp_* counters to identify sort and temp-table hotspots.<\/p>\n\n<h2>Subqueries, Semi-Joins, and Materialization<\/h2>\n\n<p>Many subqueries can be efficiently restructured during preparation. IN\/EXISTS constructs can be used as <strong>Semi-Join<\/strong> run, using strategies such as materialization or LooseScan. I check whether the optimizer is a <strong>derived_merge<\/strong> was able to perform: If a derived table (or a WITH-CTE) is pushed into the outer plan, its indexes are immediately available. If that doesn't work, the subquery ends up in a temporary table\u2014in which case, if feasible, I give it a primary key (e.g., using SELECT DISTINCT\/ORDER BY on key columns) so that joins on it don't end up in limbo.<\/p>\n\n<pre><code>-- Example: EXISTS instead of IN and a merge-able derived table\nSELECT o.id\nFROM orders o\nWHERE EXISTS (\n  SELECT 1 FROM payments p\n  WHERE p.order_id = o.id AND p.state = 'captured'\n);\n\n-- Derivation with distinct keys\nWITH paid_orders AS (\n  SELECT DISTINCT order_id\n  FROM payments\n  WHERE state = 'captured'\n)\nSELECT o.*\nFROM orders o\nJOIN paid_orders po ON po.order_id = o.id;\n<\/code><\/pre>\n\n<p>I use EXPLAIN FORMAT=JSON to check whether <strong>materialized<\/strong> or <strong>dependent subquery<\/strong> was selected and whether conditions (<strong>condition pushdown<\/strong>) take action early enough.<\/p>\n\n<h2>Partitioning and Pruning<\/h2>\n\n<p>Partitioning is no substitute for indexes, but it can <strong>Amount of data per access<\/strong> drastically reduce. The optimizer only prunes correctly if the predicate meets the <strong>Partition Key<\/strong> is unambiguous and not obscured by functions. I therefore avoid expressions like DATE(created_at) in the WHERE clause on partitioned tables and work with range boundaries instead. EXPLAIN shows which partitions are read; wide ranges indicate poor pruning.<\/p>\n\n<p>Too many small partitions increase planning overhead. I therefore choose a reasonable level of granularity (e.g., monthly instead of daily), keep statistics up to date for each partition (ANALYZE PARTITION), and check whether important indexes are present locally in the partitions. For migration projects, I factor in the impact on replication and backup\u2014both of which influence how aggressively I partition.<\/p>\n\n<h2>Sargability and Rewrite Patterns<\/h2>\n\n<p>The simplest lever remains <strong>Sargability<\/strong> \u2013 Conditions that make indexes usable. I avoid functions on columns in the WHERE clause, reduce constants to the column level, and break down OR conditions into <strong>UNION ALL<\/strong>. A BTREE index is useless for LIKE searches without a leading anchor (\"%foo\"); for these, I plan to use full-text search or a suitable search service. For calculations, I use <strong>Indexed generated columns<\/strong>, so that the optimizer can identify the logic in the index.<\/p>\n\n<pre><code>-- Anti-pattern: Function on a column\nWHERE DATE(created_at) = '2026-08-01'\n-- Better: Range on raw value\nWHERE created_at &gt;= '2026-08-01' AND created_at &lt; &#039;2026-08-02&#039;\n\n-- Anti-pattern: OR prevents indexing\nWHERE status = &#039;open&#039; OR customer_id = 42\n-- Better: Two queries using UNION ALL, each with its own index\n(SELECT ... WHERE status = &#039;open&#039;)\nUNION ALL\n(SELECT ... WHERE customer_id = 42&#039;);\n<\/code><\/pre>\n\n<p>When it comes to composite indices, I consider the <strong>left prefix rule<\/strong> Strictly follow this rule: Sort columns by selectivity and by the sort order that will be needed later. If I need a descending ORDER BY, I take that into account in the index layout\u2014that way, I avoid a file sort.<\/p>\n\n<h2>Optimizer Switch and Cost Fine-Tuning<\/h2>\n\n<p>Before I start working on queries, I check <strong>optimizer_switch<\/strong> and memory buffers. Features such as <em>mrr<\/em>, <em>batched_key_access<\/em>, <em>index_merge<\/em>, <em>semijoin<\/em>, <em>derived_merge<\/em> or <em>condition_pushdown_for_derived<\/em> can be adjusted per session. I selectively activate candidates for a test session, measure performance using EXPLAIN ANALYZE, and roll back if there is no improvement. The join path benefits from sufficient <strong>join_buffer_size<\/strong>; large varieties of <strong>sort_buffer_size<\/strong>. At the same time, I keep an eye on the buffers in relation to concurrency to ensure that the server doesn't start swapping under parallel load.<\/p>\n\n<p>At the cost level, I adjust the previously mentioned items, if necessary <strong>optimizer_costs<\/strong> in microseconds. My approach: small, reversible steps with documented measurement points. I use <strong>LAST_QUERY_COST<\/strong> for plausibility checking and repeat measurements using realistic parameter values, because plans can depend heavily on specific literals.<\/p>\n\n<h2>Plan Stability, Regressions, and Team Workflow<\/h2>\n\n<p>Even a good plan can be disrupted by data growth or version changes <strong>tip over<\/strong>. That\u2019s why I gather execution plan data: query hashes, EXPLAIN JSON, optimizer trace snippets, and EXPLAIN ANALYZE execution times. Changes to indexes and rewrites are submitted as pull requests with before-and-after evidence. In CI\/CD environments, I automatically test critical queries against representative data sets. This is how I catch <strong>Regression Plans<\/strong> early.<\/p>\n\n<p>For sensitive cases, I keep <strong>Tips<\/strong> (FORCE INDEX, STRAIGHT_JOIN, optimizer_switch per query) are available as a last resort, but use them sparingly and with an expiration date. It\u2019s better to address the root causes\u2014statistics, indexes, query structure. In teams, a lightweight guide to scalability, index design, and measurement discipline ensures that new features don\u2019t introduce performance issues without anyone noticing.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/08\/mariadb-query-optimizer-7832.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Quick Overview: From Plan to Performance<\/h2>\n\n<p>Who the <strong>Plan<\/strong> Understanding this allows you to control performance. The parsing, preparing, optimizing, and executing phases reveal where time is lost. The time-based cost model introduced in version 11.0, along with well-maintained statistics and histograms, makes estimates reliable. EXPLAIN, EXPLAIN ANALYZE, and the Optimizer Trace provide transparency, which I translate into concrete actions. With a clean index strategy, clear query design, and appropriate infrastructure, MariaDB queries consistently deliver fast results.<\/p>","protected":false},"excerpt":{"rendered":"<p>Learn how the MariaDB query optimizer works internally, how to analyze the SQL execution plan using EXPLAIN, and how to implement practical database tuning\u2014including tips for high-performance web applications.<\/p>","protected":false},"author":1,"featured_media":20923,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[781],"tags":[],"class_list":["post-20930","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-datenbanken-administration-anleitungen"],"acf":[],"_wp_attached_file":null,"_wp_attachment_metadata":null,"litespeed-optimize-size":null,"litespeed-optimize-set":null,"_elementor_source_image_hash":null,"_wp_attachment_image_alt":null,"stockpack_author_name":null,"stockpack_author_url":null,"stockpack_provider":null,"stockpack_image_url":null,"stockpack_license":null,"stockpack_license_url":null,"stockpack_modification":null,"color":null,"original_id":null,"original_url":null,"original_link":null,"unsplash_location":null,"unsplash_sponsor":null,"unsplash_exif":null,"unsplash_attachment_metadata":null,"_elementor_is_screenshot":null,"surfer_file_name":null,"surfer_file_original_url":null,"envato_tk_source_kit":null,"envato_tk_source_index":null,"envato_tk_manifest":null,"envato_tk_folder_name":null,"envato_tk_builder":null,"envato_elements_download_event":null,"_menu_item_type":null,"_menu_item_menu_item_parent":null,"_menu_item_object_id":null,"_menu_item_object":null,"_menu_item_target":null,"_menu_item_classes":null,"_menu_item_xfn":null,"_menu_item_url":null,"_trp_menu_languages":null,"rank_math_primary_category":null,"rank_math_title":null,"inline_featured_image":null,"_yoast_wpseo_primary_category":null,"rank_math_schema_blogposting":null,"rank_math_schema_videoobject":null,"_oembed_049c719bc4a9f89deaead66a7da9fddc":null,"_oembed_time_049c719bc4a9f89deaead66a7da9fddc":null,"_yoast_wpseo_focuskw":null,"_yoast_wpseo_linkdex":null,"_oembed_27e3473bf8bec795fbeb3a9d38489348":null,"_oembed_c3b0f6959478faf92a1f343d8f96b19e":null,"_trp_translated_slug_en_us":null,"_wp_desired_post_slug":null,"_yoast_wpseo_title":null,"tldname":null,"tldpreis":null,"tldrubrik":null,"tldpolicylink":null,"tldsize":null,"tldregistrierungsdauer":null,"tldtransfer":null,"tldwhoisprivacy":null,"tldregistrarchange":null,"tldregistrantchange":null,"tldwhoisupdate":null,"tldnameserverupdate":null,"tlddeletesofort":null,"tlddeleteexpire":null,"tldumlaute":null,"tldrestore":null,"tldsubcategory":null,"tldbildname":null,"tldbildurl":null,"tldclean":null,"tldcategory":null,"tldpolicy":null,"tldbesonderheiten":null,"tld_bedeutung":null,"_oembed_d167040d816d8f94c072940c8009f5f8":null,"_oembed_b0a0fa59ef14f8870da2c63f2027d064":null,"_oembed_4792fa4dfb2a8f09ab950a73b7f313ba":null,"_oembed_33ceb1fe54a8ab775d9410abf699878d":null,"_oembed_fd7014d14d919b45ec004937c0db9335":null,"_oembed_21a029d076783ec3e8042698c351bd7e":null,"_oembed_be5ea8a0c7b18e658f08cc571a909452":null,"_oembed_a9ca7a298b19f9b48ec5914e010294d2":null,"_oembed_f8db6b27d08a2bb1f920e7647808899a":null,"_oembed_168ebde5096e77d8a89326519af9e022":null,"_oembed_cdb76f1b345b42743edfe25481b6f98f":null,"_oembed_87b0613611ae54e86e8864265404b0a1":null,"_oembed_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_oembed_time_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_tldname":null,"_tldclean":null,"_tldpreis":null,"_tldcategory":null,"_tldsubcategory":null,"_tldpolicy":null,"_tldpolicylink":null,"_tldsize":null,"_tldregistrierungsdauer":null,"_tldtransfer":null,"_tldwhoisprivacy":null,"_tldregistrarchange":null,"_tldregistrantchange":null,"_tldwhoisupdate":null,"_tldnameserverupdate":null,"_tlddeletesofort":null,"_tlddeleteexpire":null,"_tldumlaute":null,"_tldrestore":null,"_tldbildname":null,"_tldbildurl":null,"_tld_bedeutung":null,"_tldbesonderheiten":null,"_oembed_ad96e4112edb9f8ffa35731d4098bc6b":null,"_oembed_8357e2b8a2575c74ed5978f262a10126":null,"_oembed_3d5fea5103dd0d22ec5d6a33eff7f863":null,"_eael_widget_elements":null,"_oembed_0d8a206f09633e3d62b95a15a4dd0487":null,"_oembed_time_0d8a206f09633e3d62b95a15a4dd0487":null,"_aioseo_description":null,"_eb_attr":null,"_eb_data_table":null,"_oembed_819a879e7da16dd629cfd15a97334c8a":null,"_oembed_time_819a879e7da16dd629cfd15a97334c8a":null,"_acf_changed":null,"_wpcode_auto_insert":null,"_edit_last":null,"_edit_lock":null,"_oembed_e7b913c6c84084ed9702cb4feb012ddd":null,"_oembed_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_time_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_03514b67990db061d7c4672de26dc514":null,"_oembed_time_03514b67990db061d7c4672de26dc514":null,"rank_math_news_sitemap_robots":null,"rank_math_robots":null,"_eael_post_view_count":"132","_trp_automatically_translated_slug_ru_ru":null,"_trp_automatically_translated_slug_et":null,"_trp_automatically_translated_slug_lv":null,"_trp_automatically_translated_slug_fr_fr":null,"_trp_automatically_translated_slug_en_us":null,"_wp_old_slug":null,"_trp_automatically_translated_slug_da_dk":null,"_trp_automatically_translated_slug_pl_pl":null,"_trp_automatically_translated_slug_es_es":null,"_trp_automatically_translated_slug_hu_hu":null,"_trp_automatically_translated_slug_fi":null,"_trp_automatically_translated_slug_ja":null,"_trp_automatically_translated_slug_lt_lt":null,"_elementor_edit_mode":null,"_elementor_template_type":null,"_elementor_version":null,"_elementor_pro_version":null,"_wp_page_template":null,"_elementor_page_settings":null,"_elementor_data":null,"_elementor_css":null,"_elementor_conditions":null,"_happyaddons_elements_cache":null,"_oembed_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_time_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_time_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_59808117857ddf57e478a31d79f76e4d":null,"_oembed_time_59808117857ddf57e478a31d79f76e4d":null,"_oembed_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_time_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_81002f7ee3604f645db4ebcfd1912acf":null,"_oembed_time_81002f7ee3604f645db4ebcfd1912acf":null,"_elementor_screenshot":null,"_oembed_7ea3429961cf98fa85da9747683af827":null,"_oembed_time_7ea3429961cf98fa85da9747683af827":null,"_elementor_controls_usage":null,"_elementor_page_assets":[],"_elementor_screenshot_failed":null,"theplus_transient_widgets":null,"_eael_custom_js":null,"_wp_old_date":null,"_trp_automatically_translated_slug_it_it":null,"_trp_automatically_translated_slug_pt_pt":null,"_trp_automatically_translated_slug_zh_cn":null,"_trp_automatically_translated_slug_nl_nl":null,"_trp_automatically_translated_slug_pt_br":null,"_trp_automatically_translated_slug_sv_se":null,"rank_math_analytic_object_id":null,"rank_math_internal_links_processed":"1","_trp_automatically_translated_slug_ro_ro":null,"_trp_automatically_translated_slug_sk_sk":null,"_trp_automatically_translated_slug_bg_bg":null,"_trp_automatically_translated_slug_sl_si":null,"litespeed_vpi_list":null,"litespeed_vpi_list_mobile":null,"rank_math_seo_score":null,"rank_math_contentai_score":null,"ilj_limitincominglinks":null,"ilj_maxincominglinks":null,"ilj_limitoutgoinglinks":null,"ilj_maxoutgoinglinks":null,"ilj_limitlinksperparagraph":null,"ilj_linksperparagraph":null,"ilj_blacklistdefinition":null,"ilj_linkdefinition":null,"_eb_reusable_block_ids":null,"rank_math_focus_keyword":"MariaDB Optimizer","rank_math_og_content_image":null,"_yoast_wpseo_metadesc":null,"_yoast_wpseo_content_score":null,"_yoast_wpseo_focuskeywords":null,"_yoast_wpseo_keywordsynonyms":null,"_yoast_wpseo_estimated-reading-time-minutes":null,"rank_math_description":null,"surfer_last_post_update":null,"surfer_last_post_update_direction":null,"surfer_keywords":null,"surfer_location":null,"surfer_draft_id":null,"surfer_permalink_hash":null,"surfer_scrape_ready":null,"_thumbnail_id":"20923","footnotes":null,"_links":{"self":[{"href":"https:\/\/webhosting.de\/en\/wp-json\/wp\/v2\/posts\/20930","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/en\/wp-json\/wp\/v2\/comments?post=20930"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/en\/wp-json\/wp\/v2\/posts\/20930\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/en\/wp-json\/wp\/v2\/media\/20923"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/en\/wp-json\/wp\/v2\/media?parent=20930"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/en\/wp-json\/wp\/v2\/categories?post=20930"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/en\/wp-json\/wp\/v2\/tags?post=20930"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}