Εντοπισμός σφαλμάτων βάσης δεδομένων
Τεχνικές εντοπισμού σφαλμάτων βάσης δεδομένων
Ενότητα με τίτλο «Τεχνικές εντοπισμού σφαλμάτων βάσης δεδομένων»Μέθοδοι και εργαλεία για τον εντοπισμό σφαλμάτων SQL ερωτημάτων και ζητημάτων βάσης δεδομένων σε εφαρμογές XOOPS.
Διαγνωστικό διάγραμμα ροής
Ενότητα με τίτλο «Διαγνωστικό διάγραμμα ροής»flowchart TD A[Database Problem] --> B{Query Runs?} B -->|No| C[Check Syntax] B -->|Yes| D{Correct Results?}
C --> C1[Run in MySQL CLI] C1 --> C2[Check EXPLAIN plan] C2 --> C3[Fix SQL]
D -->|No| E[Check Logic] D -->|Yes| F{Performance OK?}
E --> E1[Log result set] E1 --> E2[Verify data] E2 --> E3[Fix query]
F -->|Slow| G[Optimize] F -->|Fast| H[Debugging Complete]
G --> G1[Add indexes] G1 --> G2[Refactor query] G2 --> G3[Retest]Ενεργοποίηση καταγραφής ερωτημάτων
Ενότητα με τίτλο «Ενεργοποίηση καταγραφής ερωτημάτων»# Μέθοδος 1: XOOPS Λειτουργία εντοπισμού σφαλμάτων
Ενότητα με τίτλο «# Μέθοδος 1: XOOPS Λειτουργία εντοπισμού σφαλμάτων»<?php// In mainfile.phpdefine('XOOPS_DEBUG_LEVEL', 2);
// Now all queries appear in xoops_log table// Or in files: xoops_data/logs/?>Ελέγξτε τα αποτελέσματα:
# View logstail -100 xoops_data/logs/*.log
# Or query databaseSELECT * FROM xoops_log ORDER BY created DESC LIMIT 20;# Μέθοδος 2: MySQL Slow Query Log
Ενότητα με τίτλο «# Μέθοδος 2: MySQL Slow Query Log»Ενεργοποίηση στο /etc/mysql/my.cnf:
[mysqld]# Enable slow query loggingslow_query_log = 1slow_query_log_file = /var/log/mysql/slow.loglong_query_time = 1 # Log queries > 1 secondlog_queries_not_using_indexes = 1Επανεκκινήστε τη MySQL:
sudo systemctl restart mysql# orsudo systemctl restart mariadbΠροβολή αρχείου καταγραφής:
tail -100 /var/log/mysql/slow.log
# Or analyze with mysqldumpslowmysqldumpslow -s t -t 10 /var/log/mysql/slow.log# Μέθοδος 3: Γενικό αρχείο καταγραφής ερωτημάτων
Ενότητα με τίτλο «# Μέθοδος 3: Γενικό αρχείο καταγραφής ερωτημάτων»Ενεργοποίηση για όλα τα ερωτήματα (προσοχή: μεγάλα αρχεία καταγραφής):
-- EnableSET GLOBAL general_log = 'ON';SET GLOBAL log_output = 'FILE';SET GLOBAL general_log_file = '/var/log/mysql/general.log';
-- DisableSET GLOBAL general_log = 'OFF';
-- ViewSHOW VARIABLES LIKE 'general_log%';Εντοπισμός σφαλμάτων SQL στον Κώδικα
Ενότητα με τίτλο «Εντοπισμός σφαλμάτων SQL στον Κώδικα»# Εκτέλεση ερωτήματος καταγραφής
Ενότητα με τίτλο «# Εκτέλεση ερωτήματος καταγραφής»<?phprequire_once 'mainfile.php';
$ray = ray(); // If using Ray debugger
// Execute query$query = "SELECT u.uid, u.uname, COUNT(a.id) as total_articles FROM xoops_users u LEFT JOIN xoops_articles a ON u.uid = a.author_id GROUP BY u.uid ORDER BY total_articles DESC";
$ray->label('Query')->info($query);
$result = $GLOBALS['xoopsDB']->query($query);
if (!$result) { $ray->error("SQL Error: " . $GLOBALS['xoopsDB']->error); exit;}
// Log results$data = [];while ($row = $result->fetch_assoc()) { $data[] = $row;}
$ray->label('Results')->dump($data);$ray->info("Found " . count($data) . " rows");?># Μετρήστε την απόδοση ερωτήματος
Ενότητα με τίτλο «# Μετρήστε την απόδοση ερωτήματος»<?php$db = $GLOBALS['xoopsDB'];$ray = ray();
// Measure execution time$start = microtime(true);
$query = "SELECT * FROM xoops_articles LIMIT 1000";$result = $db->query($query);
$exec_time = (microtime(true) - $start) * 1000; // milliseconds
$ray->info("Query executed in: {$exec_time}ms");
// Log slow queriesif ($exec_time > 100) { // Alert if > 100ms $ray->warning("Slow query detected: {$exec_time}ms"); $ray->info($query);}?># Επαλήθευση αποτελεσμάτων ερωτήματος
Ενότητα με τίτλο «# Επαλήθευση αποτελεσμάτων ερωτήματος»<?php$db = $GLOBALS['xoopsDB'];$ray = ray();
$query = "SELECT * FROM xoops_articles WHERE author_id = 5";$result = $db->query($query);
// Check if query succeededif (!$result) { $ray->error("Query failed: " . $db->error); exit;}
// Get row count$count = $result->num_rows;$ray->info("Query returned: $count rows");
// Fetch results$articles = [];while ($row = $result->fetch_assoc()) { $articles[] = $row;}
// Verify dataif (empty($articles)) { $ray->warning("No articles found for author 5");} else { $ray->success("Found " . count($articles) . " articles"); $ray->dump($articles);}?>Ανάλυση της απόδοσης ερωτήματος
Ενότητα με τίτλο «Ανάλυση της απόδοσης ερωτήματος»# EXPLAIN Εντολή
Ενότητα με τίτλο «# EXPLAIN Εντολή»Χρησιμοποιήστε το EXPLAIN για να αναλύσετε την εκτέλεση του ερωτήματος:
-- Analyze a queryEXPLAIN SELECT * FROM xoops_articles WHERE author_id = 5;
-- With extended informationEXPLAIN EXTENDED SELECT * FROM xoops_articles WHERE author_id = 5;
-- JSON format (shows more details)EXPLAIN FORMAT=JSON SELECT * FROM xoops_articles WHERE author_id = 5\GΒασικά πεδία προς έλεγχο:
type: ALL (bad) - Full table scan INDEX (ok) - Index scan ref/const (good) - Direct index lookup range (ok) - Range scan using index
possible_keys: Indexes availablekey: Index actually usedkey_len: Length of index usedrows: Estimated rows examinedExtra: Additional info (Using where, Using index, etc.)# Παράδειγμα ανάλυσης
Ενότητα με τίτλο «# Παράδειγμα ανάλυσης»-- Slow query without indexEXPLAIN SELECT * FROM xoops_articles WHERE author_id = 5;
+----+-------------+----------+------+---------------+------+---------+------+-------+-------------+| id | select_type | table | type | possible_keys | key | key_len | rows | Extra |+----+-------------+----------+------+---------------+------+---------+------+-------+-------------+| 1 | SIMPLE | articles | ALL | NULL | NULL | NULL | 1000 | Using where |+----+-------------+----------+------+---------------+------+-------+------+-------+-------------+ ↑ No index available!
-- After adding indexALTER TABLE xoops_articles ADD INDEX (author_id);
EXPLAIN SELECT * FROM xoops_articles WHERE author_id = 5;
+----+-------------+----------+------+---------------+-----------+---------+-------+------+| id | select_type | table | type | possible_keys | key | key_len | rows | Extra|+----+-------------+----------+------+---------------+-----------+---------+-------+------+| 1 | SIMPLE | articles | ref | author_id | author_id | 4 | 10 |+----+-------------+----------+------+---------------+-----------+---------+-------+------+ ↑ Using index - much faster!Συνήθη SQL ζητήματα
Ενότητα με τίτλο «Συνήθη SQL ζητήματα»# 1. N+1 Πρόβλημα ερωτήματος
Ενότητα με τίτλο «# 1. N+1 Πρόβλημα ερωτήματος»Πρόβλημα:
<?php// WRONG: Multiple queries in loop$authors = $db->query("SELECT uid FROM xoops_users LIMIT 100");while ($author = $authors->fetch_assoc()) { // This executes 100 times! $articles = $db->query( "SELECT COUNT(*) FROM xoops_articles WHERE author_id = " . $author['uid'] ); echo $articles->fetch_row()[0];}?>Λύση: Χρησιμοποιήστε JOIN
<?php// CORRECT: One query$result = $db->query(" SELECT u.uid, u.uname, COUNT(a.id) as total FROM xoops_users u LEFT JOIN xoops_articles a ON u.uid = a.author_id GROUP BY u.uid LIMIT 100");
while ($row = $result->fetch_assoc()) { echo $row['total'];}?># 2. Λείπουν ευρετήρια
Ενότητα με τίτλο «# 2. Λείπουν ευρετήρια»** Αναγνώριση: **
-- Find queries that scan all rowsSELECT * FROM xoops_logWHERE info LIKE '%type: ALL%'ORDER BY created DESC;Προσθήκη ευρετηρίων:
-- Single column indexALTER TABLE xoops_articles ADD INDEX (author_id);ALTER TABLE xoops_articles ADD INDEX (created);
-- Composite indexALTER TABLE xoops_articles ADD INDEX (author_id, created);
-- Unique indexALTER TABLE xoops_articles ADD UNIQUE INDEX (slug);# 3. Αναποτελεσματικές WHERE Συνθήκες
Ενότητα με τίτλο «# 3. Αναποτελεσματικές WHERE Συνθήκες»Πρόβλημα:
-- Wrong: Functions prevent index useSELECT * FROM xoops_articlesWHERE YEAR(created) = 2024;
-- Wrong: OR with different columnsSELECT * FROM xoops_articlesWHERE category = 'tech' OR author_id = 5;Διάλυμα:
-- Correct: Use rangeSELECT * FROM xoops_articlesWHERE created >= '2024-01-01' AND created < '2025-01-01';
-- Correct: Use UNION for different columnsSELECT * FROM xoops_articles WHERE category = 'tech'UNIONSELECT * FROM xoops_articles WHERE author_id = 5;Ειδικά ζητήματα εντοπισμού σφαλμάτων
Ενότητα με τίτλο «Ειδικά ζητήματα εντοπισμού σφαλμάτων»# Θέμα: Το ερώτημα επιστρέφει λανθασμένα αποτελέσματα
Ενότητα με τίτλο «# Θέμα: Το ερώτημα επιστρέφει λανθασμένα αποτελέσματα»<?php$ray = ray();
// Test with sample data$author_id = 5;$ray->info("Searching for author_id = $author_id");
$query = "SELECT * FROM xoops_articles WHERE author_id = ?";$stmt = $db->prepare($query);$stmt->bind_param("i", $author_id);$stmt->execute();
$result = $stmt->get_result();$count = $result->num_rows;
$ray->info("Found: $count articles");
// Check if parameterized query helpsif ($count == 0) { // Try without parameter to debug $debug_query = "SELECT * FROM xoops_articles WHERE author_id = $author_id"; $ray->warning("Debug query: $debug_query");}
// Dump first resultif ($row = $result->fetch_assoc()) { $ray->label('First Result')->dump($row);}?># Θέμα: Ερώτημα αργής συμμετοχής
Ενότητα με τίτλο «# Θέμα: Ερώτημα αργής συμμετοχής»<?php$ray = ray();
$query = " SELECT a.id, a.title, u.uname, u.email FROM xoops_articles a LEFT JOIN xoops_users u ON a.author_id = u.uid WHERE a.status = 1 ORDER BY a.created DESC LIMIT 50";
$ray->info("Running join query");$ray->measure(function() use ($query) { $result = $GLOBALS['xoopsDB']->query($query); return $result;});
// Analyze with EXPLAIN$ray->label('Query Analysis')->info($query);?>Εκτέλεση EXPLAIN:
EXPLAIN SELECT a.id, a.title, u.uname, u.emailFROM xoops_articles aLEFT JOIN xoops_users u ON a.author_id = u.uidWHERE a.status = 1ORDER BY a.created DESCLIMIT 50\G
-- Look for:-- - type: ALL (need index)-- - Extra: Using temporary; Using filesort (inefficient)-- Fix: Add composite indexALTER TABLE xoops_articles ADD INDEX (status, created);Δημιουργία αρχείου καταγραφής ερωτημάτων εντοπισμού σφαλμάτων
Ενότητα με τίτλο «Δημιουργία αρχείου καταγραφής ερωτημάτων εντοπισμού σφαλμάτων»<?php// Create modules/yourmodule/QueryLogger.php
class QueryLogger { private static $queries = []; private static $times = [];
public static function log($query) { self::$queries[] = $query; self::$times[] = microtime(true); }
public static function execute($query) { $start = microtime(true); $result = $GLOBALS['xoopsDB']->query($query); $time = (microtime(true) - $start) * 1000;
self::log($query); self::$times[count(self::$times) - 1] = $time;
return $result; }
public static function report() { echo "<h1>Query Report</h1>"; echo "<table>"; echo "<tr><th>Query</th><th>Time (ms)</th></tr>";
foreach (self::$queries as $i => $query) { $time = self::$times[$i] ?? 0; echo "<tr>"; echo "<td><pre>" . htmlspecialchars(substr($query, 0, 100)) . "</pre></td>"; echo "<td>" . number_format($time, 2) . "</td>"; echo "</tr>"; }
echo "</table>"; }
public static function getTotalQueries() { return count(self::$queries); }
public static function getTotalTime() { return array_sum(self::$times); }}?>Χρήση:
<?phprequire_once 'QueryLogger.php';
$result = QueryLogger::execute("SELECT * FROM xoops_articles");
// Later...echo "Total queries: " . QueryLogger::getTotalQueries();echo "Total time: " . QueryLogger::getTotalTime() . "ms";QueryLogger::report();?>Λίστα ελέγχου βελτιστοποίησης βάσης δεδομένων
Ενότητα με τίτλο «Λίστα ελέγχου βελτιστοποίησης βάσης δεδομένων»graph TD A[Database Optimization] --> B["1. Identify Issues"] A --> C["2. Add Indexes"] A --> D["3. Refactor Queries"] A --> E["4. Monitor"]
B --> B1["✓ Enable slow log"] B --> B2["✓ Check EXPLAIN"] B --> B3["✓ Profile code"]
C --> C1["✓ Single column"] C --> C2["✓ Composite"] C --> C3["✓ Unique"]
D --> D1["✓ Remove N+1"] D --> D2["✓ Use JOINs"] D --> D3["✓ Add WHERE"]
E --> E1["✓ Watch slow log"] E --> E2["✓ Monitor size"] E --> E3["✓ Clean old data"]Χρήσιμο MySQL Queries
Ενότητα με τίτλο «Χρήσιμο MySQL Queries»-- Find slow tablesSELECT * FROM xoops_logWHERE info LIKE '%type: ALL%'ORDER BY created DESC LIMIT 20;
-- List all indexesSHOW INDEX FROM xoops_articles;
-- Find duplicate indexesSELECT a.table_name, a.index_name, a.seq_in_index, a.column_nameFROM information_schema.statistics aJOIN information_schema.statistics b ON a.table_name = b.table_name AND a.seq_in_index = b.seq_in_index AND a.column_name = b.column_name AND a.index_name != b.index_nameWHERE a.table_name LIKE 'xoops_%';
-- Table sizesSELECT table_name, ROUND(((data_length + index_length) / 1024 / 1024), 2) AS size_mbFROM information_schema.tablesWHERE table_schema = 'xoops_db'ORDER BY size_mb DESC;
-- Find unused indexesSELECT * FROM performance_schema.table_io_waits_summary_by_index_usageWHERE object_schema != 'mysql'AND count_star = 0ORDER BY object_name;Σχετική τεκμηρίωση
Ενότητα με τίτλο «Σχετική τεκμηρίωση»- Ενεργοποιήστε τη λειτουργία εντοπισμού σφαλμάτων
- Χρήση Ray Debugger
- Απόδοση FAQ
- Βασικές αρχές βάσης δεδομένων