டெவலப்பர்கள் பெரும்பாலும் என்னிடம் ஒரே கேள்வியைக் கேட்கிறார்கள்: "எனது API மெதுவாக உள்ளது. நான் எங்கு தொடங்குவது?" பொதுவாக சர்வரை மேம்படுத்துவது அல்லது RAM-ஐ இரட்டிப்பாக்குவதுதான் முதல் யோசனையாக இருக்கும். இது பணத்தை வீணடிக்கும், மேலும் அரிதாகவே மூல காரணத்தை சரிசெய்யும். பெரும்பாலான Laravel பயன்பாடுகளில், தேக்கநிலை (bottleneck) தரவுத்தள அடுக்கிலேயே (database layer) உள்ளது. இந்த framework-ன் நேர்த்தியான தொடரியல் (syntax), ஒவ்வொரு Eloquent அழைப்பும் இறுதியில் SQL ஆக மாறும் என்பதையும், அந்த SQL தான் பெரும்பாலும் சிக்கல்களின் தொடக்கம் என்பதையும் மறக்கச் செய்துவிடுகிறது.

ஒரு சர்வர் அமைப்பைத் தொடங்குவதற்கு முன், உங்கள் குவெரிகளை (queries) முறையாக ஆய்வு செய்யுங்கள்.

சரியான கண்டறிதலுடன் தொடங்குங்கள்

இருட்டில் ஆய்வு செய்யாதீர்கள். தேவையற்ற முறையில் குவெரிகளை மாற்றி எழுதுவது வெறும் யூகமே தவிர, அது நேரத்தை வீணடிக்கும்.

அதிக மொத்த நேரத்தை எடுத்துக்கொள்ளும் அறிக்கைகளைக் (statements) கண்டறிய வேண்டும். உண்மையான சுமையின் (real load) கீழ் உங்கள் பயன்பாட்டை கவனியுங்கள். Laravel Telescope ஒரு கோரிக்கையின் (request) போது செயல்படுத்தப்படும் ஒவ்வொரு குவெரியையும் அதன் நேரத்துடன் தெளிவாகக் காட்டும். Laravel Debugbar உள்ளூர் மேம்பாட்டின் (local development) போது அவற்றை உங்கள் உலாவியில் (browser) காண்பிக்கும், இதனால் நீங்கள் உடனடியாகப் பிழைகளைக் கண்டறியலாம். தயாரிப்புச் சூழலில் (production) சிக்கல்களைக் கண்டறிய வேண்டியிருக்கும் போது, MySQL Slow Query Log-ஐ இயக்கவும். நீங்கள் நிர்ணயிக்கும் வரம்பைத் தாண்டும் அறிக்கைகளை இது பதிவு செய்யும், இது சிறிய தரவுத் தொகுப்புகளில் (datasets) தெரியாத சிக்கல்களைக் கண்டறிய உதவும். நீங்கள் பெரிய அளவில் இயக்கும்போது, ஒரு Application Performance Monitoring கருவி மெதுவான HTTP endpoints-களை குறிப்பிட்ட தரவுத்தள அழைப்புகளுடன் தொடர்புபடுத்திப் பார்க்க உதவும்.

தரவை ஆய்வு செய்யும்போது, இரண்டு விஷயங்களைக் கவனியுங்கள்: மொத்தச் செயல்பாட்டு நேரம் (absolute execution time) மற்றும் அழைப்புத் தொடர்ச்சி (call frequency). ஒரு குவெரி 40 மில்லிசெகண்டுகள் எடுப்பது பெரிய விஷயமாகத் தெரியாது, ஆனால் அது நிமிடத்திற்கு இரண்டாயிரம் முறை இயங்குகிறது என்று தெரியவரும்போது அதன் பாதிப்பு புரியும். ஒரு மணி நேரத்திற்கு ஒருமுறை இயங்கும் மூன்று வினாடி அறிக்கை, ஒவ்வொரு பக்கத்திலும் இயங்கும் அரை வினாடி தேடலை விடக் குறைவான முக்கியத்துவம் வாய்ந்தது. அதிக பாதிப்பை ஏற்படுத்தும் சிக்கல்களை முதலில் சரிசெய்யுங்கள்.

அனைத்தையும் கேட்காதீர்கள்

SELECT * என்பது வசதியானது. ஆனால் அது அதிகச் செலவு பிடிக்கும் (expensive). நீங்கள் Model::all() என்று எழுதும்போது அல்லது நெடுவரிசைகளை (columns) குறிப்பிடாமல் முடிவுகளைப் பெறும்போது, MySQL பொருந்தும் ஒவ்வொரு வரிசைக்கும் அனைத்துத் தரவுத் புலங்களையும் (fields) இழுத்து வரும். இதில் பெரிய உரைத் புலங்கள் (text fields), JSON blobs மற்றும் அட்டவணையில் உள்ள மற்ற அனைத்தும் அடங்கும். இதனால் முடிவுகளின் தொகுப்பு (result set) வளர்கிறது, நினைவகப் பயன்பாடு (memory usage) அதிகரிக்கிறது மற்றும் பதிலைத் தயார் செய்ய (serializing) எடுக்கும் நேரமும் அதிகரிக்கிறது.

தெளிவாக இருங்கள். உங்கள் controller-க்கு id, name, மற்றும் email புலங்கள் மட்டுமே தேவை என்றால், அவற்றை மட்டும் கோரவும்:

User::select('id', 'name', 'email')->get();

Query builder-லும் இதே கொள்கை பொருந்தும். சிறிய அளவிலான payloads நெட்வொர்க்கில் வேகமாகச் செல்லும் மற்றும் உங்கள் application server-ல் குறைந்த RAM-ஐ மட்டுமே பயன்படுத்தும். இது மிக எளிதாகச் செய்யக்கூடிய ஒரு முன்னேற்றம், இருப்பினும் Laravel SELECT *-ஐ இயல்பான (default) செயல்பாடாக வைத்திருப்பதால் இதை எளிதாகத் தவிர்த்துவிடலாம்.

EXPLAIN மூலம் உங்கள் மாற்றங்களை வழிநடத்துங்கள்

முதலில் EXPLAIN-ஐ இயக்காமல் ஒரு மெதுவான குவெரியை ஒருபோதும் மாற்றியமைக்காதீர்கள் (refactor). MySQL-ல், EXPLAIN என்ற முக்கிய சொல் குவெரி செயல்படுத்தும் திட்டத்தைக் (execution plan) காட்டுகிறது. optimizer உங்கள் தரவை எவ்வாறு கண்டறியத் திட்டமிடுகிறது என்பதை இது துல்லியமாகக் காட்டுகிறது.

type நெடுவரிசையைக் கவனியுங்கள். நீங்கள் ALL என்பதைக் கண்டால், MySQL முழு அட்டவணையையும் ஸ்கேன் (full table scan) செய்கிறது என்று அர்த்தம். அதாவது உங்கள் WHERE நிபந்தனையைப் பூர்த்தி செய்ய அது ஒவ்வொரு வரியையும் படிக்கிறது. optimizer ஒரு index-ஐப் பயன்படுத்துகிறதா என்பதைப் பார்க்க key நெடுவரிசையைப் பாருங்கள். பிறகு Extra நெடுவரிசையைச் சரிபார்க்கவும். நீங்கள் Using temporary அல்லது Using filesort என்பதைக் கண்டால், உங்கள் தற்போதைய அமைப்பு குவெரியைச் சரியாகச் செயல்படுத்த முடியாததால், MySQL இடைநிலை அட்டவணைகளை (intermediate tables) உருவாக்குகிறது அல்லது நினைவகத்தில் வரிசைப்படுத்துகிறது (sorting in memory) என்று அர்த்தம்.

உங்கள் MySQL client-ல் EXPLAIN-ஐ இயக்கவும், அல்லது வெளியீட்டை வடிவமைக்கும் ஒரு கருவியைப் பயன்படுத்தவும். திட்டத்தைப் பார்த்தவுடன், பிரச்சனை விடுபட்ட index-ஆ, தவறான join-ஆ அல்லது engine-ஆல் மேம்படுத்த முடியாத ஒரு நிபந்தனையா (predicate) என்பதை நீங்கள் அறிந்து கொள்ளலாம். யூகிக்க வேண்டிய அவசியம் இருக்காது.

நோக்கத்துடன் Index செய்யுங்கள்

தேடல்களை (lookups) வேகப்படுத்த indexes மிகவும் சக்திவாய்ந்த கருவி, ஆனால் அவை நீங்கள் குவெரி செய்யும் முறையோடு ஒத்துப்போகும் போது மட்டுமே வேலை செய்யும். சரியான index இல்லையென்றால், MySQL ஒவ்வொரு வரியாக ஸ்கேன் செய்யும். ஆயிரம் வரிசைகள் கொண்ட அட்டவணையில் மேம்பாட்டு நிலையில் (development) இது சரியாகத் தோன்றலாம், ஆனால் பத்து மில்லியன் வரிசைகள் கொண்ட அட்டவணையில் தயாரிப்புச் சூழலில் (production) இது தோல்வியடையும்.

WHERE நிபந்தனைகளில் அடிக்கடி வரும் புலங்களுக்கு (fields) ஒற்றை-நெடுவரிசை (single-column) indexes மூலம் தொடங்குங்கள். நீங்கள் தொடர்ந்து status-ன் அடிப்படையில் வடிகட்டினால், status-க்கு ஒரு index-ஐச் சேர்க்கவும்.

ஒரு குவெரி பல நெடுவரிசைகளை ஒன்றாக வடிகட்டும்போது, composite indexes-க்கு மாறவும். Index-க்குள் இருக்கும் நெடுவரிசைகளின் வரிசை முக்கியமானது, ஏனெனில் MySQL composite indexes-ஐ இடமிருந்து வலமாகப் படிக்கிறது. இது leftmost prefix rule என்று அழைக்கப்படுகிறது. உங்கள் குவெரி user_id-ஆல் தேடிவிட்டு, பிறகு created_at-ஆல் வரிசைப்படுத்தினால், (user_id, created_at) என்ற composite index பெரிதும் உதவும். வரிசையை மாற்றினால், optimizer அந்த filter-க்கு index-ஐப் பயன்படுத்தாமல் போகலாம்.

ஒவ்வொரு நெடுவரிசைக்கும் index செய்யாதீர்கள். ஒவ்வொரு index-ம் insert, update மற்றும் delete செயல்பாடுகளுக்கு கூடுதல் சுமையை (overhead) ஏற்படுத்தும், ஏனெனில் MySQL அந்த அமைப்பைப் பராமரிக்க வேண்டும். அளவீட்டின் போது நீங்கள் கண்டறிந்த முறைகளின் அடிப்படையில் அவற்றைச் சரியாகச் சேர்க்கவும்.

நெடுவரிசைகளில் இருந்து செயல்பாடுகளை (Functions) விலக்கி வைத்திருங்கள்

இந்தத் தவறு குறியீடுகளை (indexes) தெரியாமலேயே முடக்கிவிடும். நீங்கள் ஒரு WHERE நிபந்தனைக்குள் (clause) ஒரு நெடுவரிசையை (column) ஒரு செயல்பாட்டிற்குள் (function) அடக்கும்போது, MySQL-ஆல் முடியாது